Skip to content
This repository has been archived by the owner on Jun 16, 2022. It is now read-only.

Commit

Permalink
Feat/live 1625 hide nft collection v3 rebased (#2452)
Browse files Browse the repository at this point in the history
* Update NFT send flow for new NFT model

* Fix all linting issues

* Add temp LLC dependency

* LIVE-1625 Implement hide NFT collection feature

* LIVE-1625 Implement unhide functionality on the settings screen

* LIVE-1625 Polishing + add hide menu to gallery

* LIVE-1625 Update hide menu wording

* Add placeholder for NFTs in Account page

* run ci

* Update onLongPress Touchable method

Co-authored-by: Juan Cortés Ross <juan@bohem.io>

* Remove useless comparison

Co-authored-by: Juan Cortés Ross <juan@bohem.io>

* run ci

* Remove hidden collections from Send flow

Co-authored-by: Gabriel R. Soares <gabriel.soares@ledger.fr>
Co-authored-by: Juan Cortés Ross <juan@bohem.io>
  • Loading branch information
3 people authored May 5, 2022
1 parent e2f5571 commit 6538f69
Show file tree
Hide file tree
Showing 18 changed files with 507 additions and 81 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
"@ledgerhq/errors": "6.10.0",
"@ledgerhq/hw-transport": "6.27.1",
"@ledgerhq/hw-transport-http": "6.27.1",
"@ledgerhq/live-common": "22.0.3",
"@ledgerhq/live-common": "https://github.com/LedgerHQ/ledger-live-common.git#0ce72dd7976ddb47844e3b2e162dd514a46196dc",
"@ledgerhq/logs": "6.10.0",
"@ledgerhq/native-ui": "^0.7.16",
"@ledgerhq/react-native-hid": "^6.28.2",
Expand Down
10 changes: 10 additions & 0 deletions src/actions/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,16 @@ export const showToken = (tokenId: string) => ({
payload: tokenId,
});

export const hideNftCollection = (collectionId: string) => ({
type: "HIDE_NFT_COLLECTION",
payload: collectionId,
});

export const unhideNftCollection = (collectionId: string) => ({
type: "UNHIDE_NFT_COLLECTION",
payload: collectionId,
});

export const dismissBanner = (bannerId: string) => ({
type: "SETTINGS_DISMISS_BANNER",
payload: bannerId,
Expand Down
58 changes: 58 additions & 0 deletions src/components/Nft/NftCollectionOptionsMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React, { useCallback } from "react";

import { useDispatch } from "react-redux";
import {
BottomDrawer,
Text,
Icons,
BoxedIcon,
Button,
Flex,
} from "@ledgerhq/native-ui";
import { Account, ProtoNFT } from "@ledgerhq/live-common/lib/types";
import { useTranslation } from "react-i18next";
import { hideNftCollection } from "../../actions/settings";

type Props = {
isOpen: boolean;
onClose: () => void;
collection: ProtoNFT[];
account: Account;
};

const NftCollectionOptionsMenu = ({
isOpen,
onClose,
collection,
account,
}: Props) => {
const { t } = useTranslation();
const dispatch = useDispatch();

const onConfirm = useCallback(() => {
dispatch(hideNftCollection(`${account.id}|${collection?.[0]?.contract}`));
onClose();
}, [dispatch, account.id, collection, onClose]);

return (
<BottomDrawer isOpen={isOpen} onClose={onClose}>
<Flex alignItems="center">
<BoxedIcon Icon={Icons.EyeNoneMedium} size={48} />
<Text variant="h1" mt={20}>
{t("settings.accounts.hideNFTCollectionModal.title")}
</Text>
<Text variant="body" textAlign="center" mt={20}>
{t("settings.accounts.hideNFTCollectionModal.desc")}
</Text>
<Button type="main" alignSelf="stretch" mt={20} onPress={onConfirm}>
{t("common.confirm")}
</Button>
<Button type="default" alignSelf="stretch" mt={20} onPress={onClose}>
{t("common.cancel")}
</Button>
</Flex>
</BottomDrawer>
);
};

export default React.memo(NftCollectionOptionsMenu);
22 changes: 11 additions & 11 deletions src/components/Nft/NftCollectionRow.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
import React, { memo } from "react";
import { StyleSheet } from "react-native";
import { RectButton } from "react-native-gesture-handler";
import {
useNftCollectionMetadata,
useNftMetadata,
} from "@ledgerhq/live-common/lib/nft";
import { ProtoNFT } from "@ledgerhq/live-common/lib/types";
import { Flex, Text } from "@ledgerhq/native-ui";
import { useTheme } from "styled-components/native";
import Skeleton from "../Skeleton";
import NftImage from "./NftImage";
import Touchable from "../Touchable";

type Props = {
collection: ProtoNFT[];
onCollectionPress: () => void;
onLongPress: () => void;
};

function NftCollectionRow({ collection, onCollectionPress }: Props) {
const { colors } = useTheme();
function NftCollectionRow({
collection,
onCollectionPress,
onLongPress,
}: Props) {
const nft = collection[0];
const { status: nftStatus, metadata: nftMetadata } = useNftMetadata(
nft?.contract,
Expand All @@ -32,10 +35,10 @@ function NftCollectionRow({ collection, onCollectionPress }: Props) {
const loading = nftStatus === "loading" || collectionStatus === "loading";

return (
<RectButton
style={styles.container}
underlayColor={colors.neutral.c50}
<Touchable
event="ShowNftCollectionMenu"
onPress={onCollectionPress}
onLongPress={onLongPress}
>
<Flex accessible flexDirection={"row"} alignItems={"center"} py={6}>
<NftImage
Expand Down Expand Up @@ -64,16 +67,13 @@ function NftCollectionRow({ collection, onCollectionPress }: Props) {
{collection?.length}
</Text>
</Flex>
</RectButton>
</Touchable>
);
}

export default memo(NftCollectionRow);

const styles = StyleSheet.create({
container: {
borderRadius: 4,
},
collectionNameSkeleton: {
height: 8,
width: 113,
Expand Down
6 changes: 6 additions & 0 deletions src/components/RootNavigator/SettingsNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import Button from "../Button";
import HelpButton from "../../screens/Settings/HelpButton";
import OnboardingStepLanguage from "../../screens/Onboarding/steps/language";
import { GenerateMockAccountSelectScreen } from "../../screens/Settings/Debug/GenerateMockAccountsSelect";
import HiddenNftCollections from "../../screens/Settings/Accounts/HiddenNftCollections";

export default function SettingsNavigator() {
const { t } = useTranslation();
Expand Down Expand Up @@ -112,6 +113,11 @@ export default function SettingsNavigator() {
component={CurrenciesList}
options={{ title: t("settings.accounts.cryptoAssets.header") }}
/>
<Stack.Screen
name={ScreenName.HiddenNftCollections}
component={HiddenNftCollections}
options={{ title: t("settings.accounts.hiddenNFTCollections") }}
/>
<Stack.Screen
name={ScreenName.CurrencySettings}
component={CurrencySettings}
Expand Down
14 changes: 14 additions & 0 deletions src/components/Touchable.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type Props = {
// will wait the promise to complete before enabling the button again
// it also displays a spinner if it takes more than WAIT_TIME_BEFORE_SPINNER
onPress: ?() => ?Promise<any> | void,
onLongPress?: ?() => ?Promise<any> | void,
children: *,
event?: string,
eventProperties?: { [key: string]: any },
Expand Down Expand Up @@ -61,6 +62,19 @@ export default class Touchable extends Component<
}
};

onLongPress = async () => {
const { onLongPress, event, eventProperties } = this.props;
if (!onLongPress) return;
if (event) {
track(event, eventProperties);
}

const res = onLongPress();
this.setState({ pending: true });
await res;
this.setState({ pending: false });
};

render() {
const {
onPress,
Expand Down
1 change: 1 addition & 0 deletions src/const/navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const ScreenName = {
ConfirmPassword: "ConfirmPassword",
CountervalueSettings: "CountervalueSettings",
CryptoAssetsSettings: "CryptoAssetsSettings",
HiddenNftCollections: "HiddenNftCollections",
CurrenciesList: "CurrenciesList",
CurrencySettings: "CurrencySettings",
DebugBLE: "DebugBLE",
Expand Down
10 changes: 9 additions & 1 deletion src/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -1753,7 +1753,8 @@
"sectionLabel": "Undelegation(s)"
},
"nft": {
"receiveNft": "Receive NFT"
"receiveNft": "Receive NFT",
"howTo": "To add NFTs, you need to <0>receive them</0> using your <1>{{currency}} address</1>."
}
},
"accounts": {
Expand Down Expand Up @@ -1904,6 +1905,13 @@
"desc": "This action will hide all <1><0>{tokenName}</0></1> accounts, you can show them again using <3>Settings > Accounts</3>.",
"confirm": "Hide token"
},
"hideNFTCollectionCTA": "Hide collection",
"hiddenNFTCollections": "Hidden NFT collections",
"hiddenNFTCollectionsDesc": "You can hide tokens by going to the account then long-pressing on a collection and selecting \"Hide Collection\".",
"hideNFTCollectionModal": {
"title": "Hide Collection?",
"desc": "You can unhide this collection in the setting options."
},
"cryptoAssets": {
"header": "Crypto assets",
"title": "Crypto assets",
Expand Down
19 changes: 19 additions & 0 deletions src/reducers/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export type SettingsState = {
graphCountervalueFirst: boolean,
hideEmptyTokenAccounts: boolean,
blacklistedTokenIds: string[],
hiddenNftCollections: string[],
dismissedBanners: string[],
hasAvailableUpdate: boolean,
theme: Theme,
Expand Down Expand Up @@ -118,6 +119,7 @@ export const INITIAL_STATE: SettingsState = {
graphCountervalueFirst: true,
hideEmptyTokenAccounts: false,
blacklistedTokenIds: [],
hiddenNftCollections: [],
dismissedBanners: [],
hasAvailableUpdate: false,
theme: "system",
Expand Down Expand Up @@ -286,6 +288,20 @@ const handlers: Object = {
blacklistedTokenIds: [...ids, tokenId],
};
},
HIDE_NFT_COLLECTION: (state: SettingsState, { payload: collectionId }) => {
const ids = state.hiddenNftCollections;
return {
...state,
hiddenNftCollections: [...ids, collectionId],
};
},
UNHIDE_NFT_COLLECTION: (state: SettingsState, { payload: collectionId }) => {
const ids = state.hiddenNftCollections;
return {
...state,
hiddenNftCollections: ids.filter(id => id !== collectionId),
};
},
SETTINGS_DISMISS_BANNER: (state, { payload }) => ({
...state,
dismissedBanners: [...state.dismissedBanners, payload],
Expand Down Expand Up @@ -486,6 +502,9 @@ export const readOnlyModeEnabledSelector = (state: State) =>
export const blacklistedTokenIdsSelector = (state: State) =>
state.settings.blacklistedTokenIds;

export const hiddenNftCollectionsSelector = (state: State) =>
state.settings.hiddenNftCollections;

// $FlowFixMe
export const exportSettingsSelector = createSelector(
counterValueCurrencySelector,
Expand Down
4 changes: 3 additions & 1 deletion src/screens/Account/ListHeaderComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { ValueChange } from "@ledgerhq/live-common/lib/portfolio/v2/types";
import { CompoundAccountSummary } from "@ledgerhq/live-common/lib/compound/types";

import { Box } from "@ledgerhq/native-ui";
import { isNFTActive } from "@ledgerhq/live-common/lib/nft";

import Header from "./Header";
import AccountGraphCard from "../../components/AccountGraphCard";
import SubAccountsList from "./SubAccountsList";
Expand Down Expand Up @@ -168,7 +170,7 @@ export function getListHeaderComponents({
</Box>,
]
: []),
...(!empty && account.type === "Account" && account.nfts?.length
...(!empty && account.type === "Account" && isNFTActive(account.currency)
? [<NftCollectionsList account={account} />]
: []),
...(compoundSummary &&
Expand Down
Loading

0 comments on commit 6538f69

Please sign in to comment.