Skip to content

Commit

Permalink
feature(ui-ux): added Get DFI-EVM screen (#4125)
Browse files Browse the repository at this point in the history
* feature(ui-ux): added Get DFI-EVM screen

* removed commented code

* updated translation

* fixed testcase

---------

Co-authored-by: Pierre Gee <pierre@cakedefi.com>
  • Loading branch information
fullstackninja864 and pierregee authored Nov 28, 2023
1 parent 065f4e6 commit 7dd1836
Show file tree
Hide file tree
Showing 11 changed files with 201 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ export function PortfolioNavigator(): JSX.Element {
const goToNetworkSelect = (): void => {
navigation.navigate("NetworkSelectionScreenPortfolio");
};
const { domain } = useDomainContext();
const isEvmDomain = domain === DomainType.EVM;
const screenOptions = useNavigatorScreenOptions();
return (
<PortfolioStack.Navigator
Expand Down Expand Up @@ -291,7 +293,10 @@ export function PortfolioNavigator(): JSX.Element {
<HeaderNetworkStatus onPress={goToNetworkSelect} />
),
headerBackTitleVisible: false,
headerTitle: translate("screens/ReceiveScreen", "Get DFI"),
headerTitle: translate(
"screens/ReceiveScreen",
isEvmDomain ? "Get DFI-EVM" : "Get DFI",
),
}}
/>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ import { TextSkeletonLoaderV2 } from "@components/TextSkeletonLoaderV2";
import BigNumber from "bignumber.js";
import { translate } from "@translations";
import { useDomainContext, DomainType } from "@contexts/DomainContext";
import { ConvertDirection } from "@screens/enum";
import { TokenNameText } from "./TokenNameText";
import { TokenAmountText } from "./TokenAmountText";
import { useEvmTokenBalances } from "../hooks/EvmTokenBalances";
import { useTokenBalance } from "../hooks/TokenBalance";

interface DFIBalaceCardProps {
denominationCurrency: string;
Expand All @@ -29,8 +30,8 @@ export function DFIBalanceCard({
denominationCurrency,
}: DFIBalaceCardProps): JSX.Element {
const { domain } = useDomainContext();
const { evmTokens } = useEvmTokenBalances();
const evmDFIToken = evmTokens.find(({ id }) => id === "0_evm");
const { dvmTokens, evmTokens } = useTokenBalance();
const evmDFIToken = evmTokens.find(({ tokenId }) => tokenId === "0_evm");
const navigation = useNavigation<NavigationProp<PortfolioParamList>>();
const DFIToken = useSelector((state: RootState) =>
DFITokenSelector(state.wallet),
Expand All @@ -46,7 +47,7 @@ export function DFIBalanceCard({
const { getTokenPrice } = useTokenPrice(denominationCurrency); // input based on selected denomination from portfolio tab
const isEvmDomain = domain === DomainType.EVM;
const tokenAmount = isEvmDomain
? new BigNumber(evmDFIToken?.amount ?? 0)
? new BigNumber(evmDFIToken?.available ?? 0)
: new BigNumber(DFIUnified.amount ?? 0);
const usdAmount = getTokenPrice(
DFIUnified.symbol,
Expand All @@ -55,10 +56,28 @@ export function DFIBalanceCard({
);
const DFIIcon = getNativeIcon("_UTXO");
const EvmDFIIcon = getNativeIcon("EvmDFI");

const isPositiveBalance = isEvmDomain
? new BigNumber(evmDFIToken?.amount ?? 0).gt(0)
? new BigNumber(evmDFIToken?.available ?? 0).gt(0)
: new BigNumber(DFIUtxo.amount ?? 0).plus(DFIToken.amount ?? 0).gt(0);

const getDFI = () => {
if (isEvmDomain && new BigNumber(DFIToken.amount ?? 0).gt(0)) {
const convertDirection = ConvertDirection.evmToDvm;
const dfiToken = dvmTokens.find((token) => token.tokenId === "0");
const evmDFIToken = evmTokens.find((token) => token.tokenId === "0_evm");
return navigation.navigate({
name: "ConvertScreen",
params: {
sourceToken: dfiToken,
targetToken: evmDFIToken,
convertDirection,
},
merge: true,
});
}
return navigation.navigate("GetDFIScreen");
};

return (
<View style={tailwind("mx-5 mt-2 rounded-lg-v2")} testID="dfi_balance_card">
<View style={tailwind("flex-col rounded-lg-v2 overflow-hidden")}>
Expand Down Expand Up @@ -139,14 +158,21 @@ export function DFIBalanceCard({
)}
</View>
</ThemedTouchableOpacityV2>
{hasFetchedToken && !isPositiveBalance && !isEvmDomain && <GetDFIBtn />}
{hasFetchedToken && !isPositiveBalance && (
<GetDFIBtn isEvmDomain={isEvmDomain} onPress={getDFI} />
)}
</View>
</View>
);
}

function GetDFIBtn(): JSX.Element {
const navigation = useNavigation<NavigationProp<PortfolioParamList>>();
function GetDFIBtn({
isEvmDomain,
onPress,
}: {
isEvmDomain: boolean;
onPress: () => void;
}): JSX.Element {
return (
<LinearGradient
start={[0, 0]}
Expand All @@ -167,15 +193,18 @@ function GetDFIBtn(): JSX.Element {
<TouchableOpacity
testID="get_DFI_btn"
// @ts-ignore
onPress={() => navigation.navigate("GetDFIScreen")}
onPress={onPress}
activeOpacity={0.7}
>
<Text
style={tailwind(
"font-semibold-v2 text-sm my-1 text-center text-mono-light-v2-100",
)}
>
{translate("screens/GetDFIScreen", "Get DFI now!")}
{translate(
"screens/GetDFIScreen",
isEvmDomain ? "Get DFI-EVM now!" : "Get DFI now!",
)}
</Text>
</TouchableOpacity>
</LinearGradient>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { block } from "@waveshq/walletkit-ui/dist/store/block";
import { GetDFIScreen } from "./GetDFIScreen";

jest.mock("@shared-contexts/WalletContext");
jest.mock("@contexts/DomainContext");
jest.mock("react-native-popover-view");

jest.mock("expo-clipboard", () => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
import { useToast } from "react-native-toast-notifications";
import { useThemeContext } from "@waveshq/walletkit-ui";
import { useWalletContext } from "@shared-contexts/WalletContext";
import { tailwind } from "@tailwind";
import { getColor, tailwind } from "@tailwind";
import { translate } from "@translations";
import {
NativeLoggingProps,
Expand All @@ -28,10 +28,12 @@ import { useSelector } from "react-redux";
import { RootState } from "@store";
import { useWhaleApiClient } from "@waveshq/walletkit-ui/dist/contexts";
import { PortfolioParamList } from "@screens/AppNavigator/screens/Portfolio/PortfolioNavigator";
import { ConvertIcon } from "@components/icons/assets/ConvertIcon";
import { DomainType, useDomainContext } from "@contexts/DomainContext";

export async function onShare(
address: string,
logger: NativeLoggingProps
logger: NativeLoggingProps,
): Promise<void> {
try {
await Share.share({
Expand All @@ -45,6 +47,8 @@ export async function onShare(
type Props = StackScreenProps<PortfolioParamList, "GetDFIScreen">;

export function GetDFIScreen({ navigation }: Props): JSX.Element {
const { domain } = useDomainContext();
const isEvmDomain = domain === DomainType.EVM;
return (
<ThemedScrollViewV2
contentContainerStyle={tailwind("mx-5 pb-24")}
Expand All @@ -53,6 +57,7 @@ export function GetDFIScreen({ navigation }: Props): JSX.Element {
>
<StepOne onPress={() => navigation.navigate("MarketplaceScreen")} />
<StepTwo />
{isEvmDomain && <StepThree />}
<DFIOraclePrice />
</ThemedScrollViewV2>
);
Expand All @@ -76,7 +81,7 @@ function StepOne({ onPress }: { onPress: () => void }): JSX.Element {
>
<ThemedTouchableOpacityV2
style={tailwind(
"flex flex-row items-center justify-between py-4.5 ml-5 mr-4"
"flex flex-row items-center justify-between py-4.5 ml-5 mr-4",
)}
onPress={onPress}
testID="get_exchanges"
Expand All @@ -94,7 +99,7 @@ function StepOne({ onPress }: { onPress: () => void }): JSX.Element {
</ThemedTouchableOpacityV2>
</ThemedViewV2>
<TouchableOpacity
onPress={async () => await openURL("https://defichain.com/dfi")}
onPress={async () => await openURL("https://defichain.com/explore/dfi")}
style={tailwind("flex flex-row items-center mx-5 mt-2")}
>
<ThemedIcon
Expand Down Expand Up @@ -128,7 +133,7 @@ function StepTwo(): JSX.Element {
setShowToast(true);
setTimeout(() => setShowToast(false), TOAST_DURATION);
}, 500),
[showToast]
[showToast],
);

useEffect(() => {
Expand Down Expand Up @@ -202,7 +207,7 @@ function StepTwo(): JSX.Element {
isLight
? "border-mono-light-v2-700"
: "border-mono-dark-v2-700"
}`
}`,
)}
testID="share_button"
>
Expand All @@ -221,6 +226,77 @@ function StepTwo(): JSX.Element {
);
}

function StepThree(): JSX.Element {
const { isLight } = useThemeContext();

return (
<>
<View style={tailwind("mt-8 px-5")}>
<View style={tailwind("pb-4")}>
<ThemedTextV2 style={tailwind("text-xs font-normal-v2")}>
{translate("screens/GetDFIScreen", "STEP 3")}
</ThemedTextV2>
<ThemedTextV2 style={tailwind("font-normal-v2")}>
{translate("screens/GetDFIScreen", "Convert to DFI-EVM tokens")}
</ThemedTextV2>
</View>
<View style={tailwind("flex flex-row")}>
<View style={tailwind("items-center")}>
<ThemedViewV2
style={[
tailwind(
"rounded-lg p-2 drop-shadow-lg flex flex-col justify-around items-center border-0.5 rounded-lg-v2",
),
{ width: 120, height: 120 },
]}
dark={tailwind("bg-mono-dark-v2-00 border-mono-dark-v2-200")}
light={tailwind("bg-mono-light-v2-00 border-mono-light-v2-200")}
>
<View>
<ThemedViewV2
style={tailwind(
"w-15 h-15 flex flex-row justify-around items-center rounded-full",
)}
dark={tailwind("bg-mono-dark-v2-100")}
light={tailwind("bg-mono-light-v2-100")}
>
<ConvertIcon
color={getColor(
isLight ? "mono-light-v2-900" : "mono-dark-v2-900",
)}
iconSize={24}
/>
</ThemedViewV2>
<ThemedTextV2
style={tailwind(
"font-normal-v2 text-xs flex flex-row justify-around items-center mt-2",
)}
dark={tailwind("text-mono-dark-v2-500")}
light={tailwind("text-mono-light-v2-500")}
>
{translate("screens/GetDFIScreen", "Convert")}
</ThemedTextV2>
</View>
</ThemedViewV2>
</View>
<View
style={tailwind(
"pl-5 justify-between flex flex-row items-center flex-1",
)}
>
<ThemedTextV2 style={tailwind("text-sm font-normal-v2 flex-1")}>
{translate(
"screens/GetDFIScreen",
"Tap on “Convert” quick action on your DVM wallet to start the conversion",
)}
</ThemedTextV2>
</View>
</View>
</View>
</>
);
}

function DFIOraclePrice(): JSX.Element {
const [price, setPrice] = useState("0");
const client = useWhaleApiClient();
Expand All @@ -242,7 +318,7 @@ function DFIOraclePrice(): JSX.Element {
dark={tailwind("border-mono-dark-v2-900")}
light={tailwind("border-mono-light-v2-900")}
style={tailwind(
"flex flex-row items-center justify-between rounded-lg mt-10 px-5 py-4.5 border-0.5"
"flex flex-row items-center justify-between rounded-lg mt-10 px-5 py-4.5 border-0.5",
)}
>
<TouchableOpacity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import { NavigationProp, useNavigation } from "@react-navigation/native";
import { tailwind } from "@tailwind";
import { RootState } from "@store";
import { translate } from "@translations";
import { tokensSelector, WalletToken } from "@waveshq/walletkit-ui/dist/store";
import {
DFITokenSelector,
tokensSelector,
WalletToken,
} from "@waveshq/walletkit-ui/dist/store";
import { useDebounce } from "@hooks/useDebounce";
import { useThemeContext } from "@waveshq/walletkit-ui";
import { useTokenPrice } from "@screens/AppNavigator/screens/Portfolio/hooks/TokenPrice";
Expand All @@ -28,11 +32,13 @@ import {
} from "@components/SkeletonLoader";
import { ListRenderItemInfo } from "@shopify/flash-list";
import { DomainType, useDomainContext } from "@contexts/DomainContext";
import { ConvertDirection } from "@screens/enum";
import { PortfolioParamList } from "../PortfolioNavigator";
import { ActiveUSDValueV2 } from "../../Loans/VaultDetail/components/ActiveUSDValueV2";
import { TokenIcon } from "../components/TokenIcon";
import { TokenNameText } from "../components/TokenNameText";
import { useEvmTokenBalances } from "../hooks/EvmTokenBalances";
import { useTokenBalance } from "../hooks/TokenBalance";

export interface TokenSelectionItem extends BottomSheetToken {
usdAmount: BigNumber;
Expand Down Expand Up @@ -262,6 +268,29 @@ function EmptyAsset({
navigation: NavigationProp<PortfolioParamList>;
isEvmDomain: boolean;
}): JSX.Element {
const { dvmTokens, evmTokens } = useTokenBalance();
const DFIToken = useSelector((state: RootState) =>
DFITokenSelector(state.wallet),
);

const getDFI = () => {
if (isEvmDomain && new BigNumber(DFIToken.amount).gt(0)) {
const convertDirection = ConvertDirection.evmToDvm;
const dfiToken = dvmTokens.find((token) => token.tokenId === "0");
const evmDFIToken = evmTokens.find((token) => token.tokenId === "0_evm");
return navigation.navigate({
name: "ConvertScreen",
params: {
sourceToken: dfiToken,
targetToken: evmDFIToken,
convertDirection,
},
merge: true,
});
}
return navigation.navigate("GetDFIScreen");
};

return (
<ThemedScrollViewV2
contentContainerStyle={tailwind(
Expand Down Expand Up @@ -295,13 +324,11 @@ function EmptyAsset({
)}
</ThemedTextV2>
</View>
{!isEvmDomain && (
<ButtonV2
onPress={() => navigation.navigate("GetDFIScreen" as any)}
styleProps="w-full mb-14 pb-1"
label={translate("screens/GetDFIScreen", "Get DFI")}
/>
)}
<ButtonV2
onPress={getDFI}
styleProps="w-full mb-14 pb-1"
label={translate("screens/GetDFIScreen", "Get DFI")}
/>
</ThemedScrollViewV2>
);
}
Expand Down
Loading

0 comments on commit 7dd1836

Please sign in to comment.