Skip to content

Commit

Permalink
Merge pull request #228 from k0beLeenders/mobile-xnft-changes
Browse files Browse the repository at this point in the history
feat(mfi-v2-xnft): xnft refine & dust cleanup and layout fixes
  • Loading branch information
losman0s authored Sep 10, 2023
2 parents eb606e0 + 67df5be commit cd4dadd
Show file tree
Hide file tree
Showing 11 changed files with 165 additions and 68 deletions.
7 changes: 4 additions & 3 deletions apps/marginfi-v2-xnft/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { SwapContextProvider } from "~/context";
import { useConnection } from "~/hooks/useConnection";
import { useWallet } from "~/hooks/useWallet";
import { ROUTE_CACHE_DURATION } from "~/consts";
import { PieChartIcon, ReceiveMoneyIcon, TokenSwapIcon } from "~/assets/icons";

require("~/styles/globals.css");
require("~/styles/fonts.css");
Expand Down Expand Up @@ -82,7 +83,7 @@ function TabNavigator() {
options={{
header: (props: BottomTabHeaderProps) => <LogoTitle />,
tabBarLabel: "Lend",
tabBarIcon: ({ color, size }) => <MaterialCommunityIcons name="account" color={color} size={size} />,
tabBarIcon: ({ color, size }) => <ReceiveMoneyIcon color={color} height={size} width={size} />,
}}
/>
<Tab.Screen
Expand All @@ -91,7 +92,7 @@ function TabNavigator() {
options={{
header: (props: BottomTabHeaderProps) => <LogoTitle />,
tabBarLabel: "Swap",
tabBarIcon: ({ color, size }) => <MaterialCommunityIcons name="bank" color={color} size={size} />,
tabBarIcon: ({ color, size }) => <TokenSwapIcon color={color} height={size} width={size} />,
}}
/>
<Tab.Screen
Expand All @@ -100,7 +101,7 @@ function TabNavigator() {
options={{
header: (props: BottomTabHeaderProps) => <LogoTitle />,
tabBarLabel: "Portfolio",
tabBarIcon: ({ color, size }) => <MaterialCommunityIcons name="home" color={color} size={size} />,
tabBarIcon: ({ color, size }) => <PieChartIcon color={color} height={size} width={size} />,
}}
/>
</Tab.Navigator>
Expand Down
16 changes: 16 additions & 0 deletions apps/marginfi-v2-xnft/src/assets/icons/PieChartIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from "react";

interface PieChartIconProps extends React.SVGAttributes<SVGElement> {
color?: string;
}

export const PieChartIcon: React.FC<PieChartIconProps> = ({ width = "24", height = "24", color = "white" }) => {
return (
<svg width={width} height={height} viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path
d="M11 2.04932V12.9999H21.9506C21.4489 18.0533 17.1853 21.9999 12 21.9999C6.47715 21.9999 2 17.5228 2 11.9999C2 6.81459 5.94668 2.55104 11 2.04932ZM13 2.04932C17.7244 2.51839 21.4816 6.27552 21.9506 10.9999H13V2.04932Z"
fill={color}
/>
</svg>
);
};
19 changes: 19 additions & 0 deletions apps/marginfi-v2-xnft/src/assets/icons/ReceiveMoneyIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from "react";

interface ReceiveMoneyIconProps extends React.SVGAttributes<SVGElement> {
color?: string;
}

export const ReceiveMoneyIcon: React.FC<ReceiveMoneyIconProps> = ({ width = "24", height = "24", color = "black" }) => {
return (
<svg width={width} height={height} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<g transform="translate(0,0)">
<path
d="M258 21.89c-.5 0-1.2 0-1.8.12-4.6.85-10.1 5.1-13.7 14.81-3.8 9.7-4.6 23.53-1.3 38.34 3.4 14.63 10.4 27.24 18.2 34.94 7.6 7.7 14.5 9.8 19.1 9 4.8-.7 10.1-5.1 13.7-14.7 3.8-9.64 4.8-23.66 1.4-38.35-3.5-14.8-10.4-27.29-18.2-34.94-6.6-6.8-12.7-9.22-17.4-9.22zM373.4 151.4c-11 .3-24.9 3.2-38.4 8.9-15.6 6.8-27.6 15.9-34.2 24.5-6.6 8.3-7.2 14.6-5.1 18.3 2.2 3.7 8.3 7.2 20 7.7 11.7.7 27.5-2.2 43-8.8 15.5-6.7 27.7-15.9 34.3-24.3 6.6-8.3 7.1-14.8 5-18.5-2.1-3.8-8.3-7.1-20-7.5-1.6-.3-3-.3-4.6-.3zm-136.3 92.9c-6.6.1-12.6.9-18 2.3-11.8 3-18.6 8.4-20.8 14.9-2.5 6.5 0 14.3 7.8 22.7 8.2 8.2 21.7 16.1 38.5 20.5 16.7 4.4 32.8 4.3 44.8 1.1 12.1-3.1 18.9-8.6 21.1-15 2.3-6.5 0-14.2-8.1-22.7-7.9-8.2-21.4-16.1-38.2-20.4-9.5-2.5-18.8-3.5-27.1-3.4zm160.7 58.1L336 331.7c4.2.2 14.7.5 14.7.5l6.6 8.7 54.7-28.5-14.2-10zm-54.5.1l-57.4 27.2c5.5.3 18.5.5 23.7.8l49.8-23.6-16.1-4.4zm92.6 10.8l-70.5 37.4 14.5 18.7 74.5-44.6-18.5-11.5zm-278.8 9.1a40.33 40.33 0 0 0-9 1c-71.5 16.5-113.7 17.9-126.2 17.9H18v107.5s11.6-1.7 30.9-1.8c37.3 0 103 6.4 167 43.8 3.4 2.1 10.7 2.9 19.8 2.9 24.3 0 61.2-5.8 69.7-9C391 452.6 494 364.5 494 364.5l-32.5-28.4s-79.8 50.9-89.9 55.8c-91.1 44.7-164.9 16.8-164.9 16.8s119.9 3 158.4-27.3l-22.6-34s-82.8-2.3-112.3-6.2c-15.4-2-48.7-18.8-73.1-18.8z"
fill={color}
fillOpacity="1"
/>
</g>
</svg>
);
};
16 changes: 16 additions & 0 deletions apps/marginfi-v2-xnft/src/assets/icons/TokenSwapIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from "react";

interface TokenSwapIconProps extends React.SVGAttributes<SVGElement> {
color?: string;
}

export const TokenSwapIcon: React.FC<TokenSwapIconProps> = ({ width = "24", height = "24", color = "black" }) => {
return (
<svg width={width} height={height} viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path
d="M21.5 9C21.5 11.7039 19.849 14.0223 17.5 15.0018L17.5 15C17.5 10.3056 13.6944 6.5 9.00001 6.5L8.99817 6.5C9.97773 4.15105 12.2961 2.5 15 2.5C18.5899 2.5 21.5 5.41015 21.5 9ZM7 3C4.79086 3 3 4.79086 3 7V8.5H5V7C5 5.89543 5.89543 5 7 5H8.5V3H7ZM19 15.5V17C19 18.1046 18.1046 19 17 19H15.5V21H17C19.2091 21 21 19.2091 21 17V15.5H19ZM9 21.5C12.5899 21.5 15.5 18.5899 15.5 15C15.5 11.4101 12.5899 8.5 9 8.5C5.41015 8.5 2.5 11.4101 2.5 15C2.5 18.5899 5.41015 21.5 9 21.5ZM9 12.5L11.5 15L9 17.5L6.5 15L9 12.5Z"
fill={color}
/>
</svg>
);
};
3 changes: 0 additions & 3 deletions apps/marginfi-v2-xnft/src/assets/icons/chevron-down.svg

This file was deleted.

3 changes: 3 additions & 0 deletions apps/marginfi-v2-xnft/src/assets/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ export * from "./RefreshIcon";
export * from "./SettingsIcon";
export * from "./CloseIcon";
export * from "./ErrorIcon";
export * from "./PieChartIcon";
export * from "./ReceiveMoneyIcon";
export * from "./TokenSwapIcon";
46 changes: 43 additions & 3 deletions apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { MarginfiAccountWrapper, MarginfiClient } from "@mrgnlabs/marginfi-clien
import { PoolCardPosition } from "./PoolCardPosition";
import { useConnection } from "~/hooks/useConnection";
import { ActionType, Emissions, ExtendedBankInfo, FEE_MARGIN, getCurrentAction } from "@mrgnlabs/marginfi-v2-ui-state";
import { showErrorToast } from "~/utils";
import { showErrorToast, showSuccessToast } from "~/utils";
import { percentFormatter, usdFormatter } from "@mrgnlabs/mrgn-common";

type Props = {
Expand Down Expand Up @@ -120,6 +120,8 @@ export function PoolCard({
const withdrawAll = bankInfo.isActive ? borrowOrLendAmount === bankInfo.position.amount : false;
await _marginfiAccount.withdraw(borrowOrLendAmount, bankInfo.address, withdrawAll);
}

showSuccessToast(`${currentAction + "ing"} ${borrowOrLendAmount} ${bankInfo.meta.tokenSymbol} 👍`);
} catch (error: any) {
console.log(`Error while ${currentAction + "ing"}`);
console.log(error);
Expand All @@ -136,8 +138,46 @@ export function PoolCard({
[bankInfo, connection, currentAction, marginfiAccount, marginfiClient, nativeSolBalance, reloadBanks]
);

const closeBalance = useCallback(async () => {
if (!marginfiAccount) {
showErrorToast("marginfi account not ready.");
return;
}

if (!bankInfo.isActive) {
showErrorToast("no position to close.");
return;
}

try {
if (bankInfo.position.isLending) {
await marginfiAccount.withdraw(0, bankInfo.address, true);
} else {
await marginfiAccount.repay(0, bankInfo.address, true);
}
showSuccessToast("Closing 👍");
} catch (error: any) {
showSuccessToast(`Error while closing balance: ${error.message}`);
console.log(`Error while closing balance`);
console.log(error);
}

// TODO: set values back to 0
try {
await reloadBanks();
} catch (error: any) {
console.log("Error while reloading state");
console.log(error);
}
}, [bankInfo, marginfiAccount, reloadBanks]);

return (
<View style={tw`bg-[#1C2125] rounded-xl px-12px py-16px flex flex-column gap-16px `}>
<View
style={[
tw`bg-[#1C2125] rounded-xl px-12px py-16px flex flex-column gap-16px w-[341px]`,
// { height: "fit-content" },
]}
>
<View style={tw`flex flex-row justify-between`}>
<View style={tw`flex flex-row gap-7px`}>
<Image style={styles.logo} source={{ uri: bankInfo.meta.tokenLogoUri }} alt={bankInfo.meta.tokenSymbol} />
Expand All @@ -163,7 +203,7 @@ export function PoolCard({
currentAction={currentAction}
isBankFilled={isInLendingMode ? depositFilled >= 0.9999 : borrowFilled >= 0.9999}
bank={bankInfo}
onAction={(amount) => borrowOrLend(amount)}
onAction={(amount) => (amount ? borrowOrLend(amount) : closeBalance())}
/>
</View>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import { View, Text, Pressable } from "react-native";
import tw from "~/styles/tailwind";
import { NumberInput, PrimaryButton, SecondaryButton } from "~/components/Common";
import { ActionType, ExtendedBankInfo } from "@mrgnlabs/marginfi-v2-ui-state";
import { uiToNative } from "@mrgnlabs/mrgn-common";

type Props = {
currentAction: ActionType;
bank: ExtendedBankInfo;
isBankFilled: boolean;
onAction: (amount: string) => void;
onAction: (amount?: string) => void;
};

export function PoolCardActions({ currentAction, bank, isBankFilled, onAction }: Props) {
Expand All @@ -27,20 +28,20 @@ export function PoolCardActions({ currentAction, bank, isBankFilled, onAction }:
}
}, [bank.userInfo, currentAction]);

const isDisabled = useMemo(() => {
switch (currentAction) {
case ActionType.Deposit:
return isBankFilled;
case ActionType.Withdraw:
return false;
case ActionType.Borrow:
return isBankFilled;
case ActionType.Repay:
return false;
}
}, [currentAction, isBankFilled]);
const isDust = useMemo(
() => bank.isActive && uiToNative(bank.position.amount, bank.info.state.mintDecimals).isZero(),
[bank]
);

const isDisabled = useMemo(
() =>
(isDust && uiToNative(bank.userInfo.tokenAccount.balance, bank.info.state.mintDecimals).isZero()) ||
maxAmount === 0,
[currentAction, bank, isDust, maxAmount]
);

const buttonText = useMemo(() => {
if (isDust) return "Close";
switch (currentAction) {
case ActionType.Deposit:
return isDisabled ? "Deposits reached the limit" : "Supply";
Expand All @@ -51,7 +52,7 @@ export function PoolCardActions({ currentAction, bank, isBankFilled, onAction }:
case ActionType.Repay:
return "Repay";
}
}, [currentAction, isDisabled]);
}, [currentAction, isDisabled, isDust]);

return (
<>
Expand All @@ -72,7 +73,7 @@ export function PoolCardActions({ currentAction, bank, isBankFilled, onAction }:
</View>
</View>
{currentAction == ActionType.Withdraw || currentAction == ActionType.Repay ? (
<SecondaryButton title={buttonText ?? ""} onPress={() => onAction(amount)} />
<SecondaryButton title={buttonText ?? ""} onPress={() => (isDust ? onAction() : onAction(amount))} />
) : (
<PrimaryButton title={buttonText ?? ""} onPress={() => onAction(amount)} />
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { View } from "react-native";
import tw from "~/styles/tailwind";

export const PoolCardSkeleton = (props?: JSX.IntrinsicAttributes & IContentLoaderProps) => (
<View style={tw`bg-[#1C2125] rounded-xl px-12px py-16px gap-16px `}>
<View style={tw`bg-[#1C2125] rounded-xl px-12px py-16px gap-16px max-w-sm min-w-[300px]`}>
<ContentLoader
speed={2}
width={310.4}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export function PoolCardStats({ bank, isInLendingMode, nativeSolBalance, bankFil
const isHigh = useMemo(() => bankFilled >= 0.9, [bankFilled]);

return (
<View style={tw`flex flex-row`}>
<View style={tw`flex flex-row h-60px`}>
<View style={tw`flex flex-col min-w-77px`}>
<Text style={tw`font-normal text-sm text-tertiary`}>Weight</Text>
<Text style={tw`font-medium text-base text-primary`}>{assetWeight}</Text>
Expand Down
88 changes: 46 additions & 42 deletions apps/marginfi-v2-xnft/src/screens/LendScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,52 +68,56 @@ export function LendScreen() {
<Text style={tw`text-base text-primary`}>Filter my positions</Text>
</View>
<Text style={tw`text-xl text-primary pl-12px`}>Global pools</Text>
{extendedBankInfos.length > 0 ? (
globalPools.length > 0 ? (
globalPools.map((extendedBankInfo, idx) => (
<PoolCard
key={idx}
bankInfo={extendedBankInfo}
nativeSolBalance={nativeSolBalance}
isInLendingMode={tabActive === "lend"}
marginfiAccount={selectedAccount}
reloadBanks={async () => {
if (!connection) return;
fetchMrgnlendState({ marginfiConfig: config.mfiConfig, connection, wallet });
}}
marginfiClient={marginfiClient}
></PoolCard>
))
<View style={tw`flex flex-row gap-2 flex-wrap`}>
{extendedBankInfos.length > 0 ? (
globalPools.length > 0 ? (
globalPools.map((extendedBankInfo, idx) => (
<PoolCard
key={idx}
bankInfo={extendedBankInfo}
nativeSolBalance={nativeSolBalance}
isInLendingMode={tabActive === "lend"}
marginfiAccount={selectedAccount}
reloadBanks={async () => {
if (!connection) return;
fetchMrgnlendState({ marginfiConfig: config.mfiConfig, connection, wallet });
}}
marginfiClient={marginfiClient}
></PoolCard>
))
) : (
<Text style={tw`text-sm text-secondary pl-12px`}>No Global Pools Found</Text>
)
) : (
<Text style={tw`text-sm text-secondary pl-12px`}>No Global Pools Found</Text>
)
) : (
<PoolCardSkeleton />
)}
<PoolCardSkeleton />
)}
</View>

<Text style={tw`text-xl text-primary pl-12px`}>Isolated pools</Text>
{extendedBankInfos.length > 0 ? (
isolatedPools.length > 0 ? (
isolatedPools.map((extendedBankInfo, idx) => (
<PoolCard
key={idx}
bankInfo={extendedBankInfo}
nativeSolBalance={nativeSolBalance}
isInLendingMode={tabActive === "lend"}
marginfiAccount={selectedAccount}
reloadBanks={async () => {
if (!connection) return;
fetchMrgnlendState({ marginfiConfig: config.mfiConfig, connection, wallet });
}}
marginfiClient={marginfiClient}
></PoolCard>
))
<View style={tw`flex flex-row gap-2 flex-wrap`}>
{extendedBankInfos.length > 0 ? (
isolatedPools.length > 0 ? (
isolatedPools.map((extendedBankInfo, idx) => (
<PoolCard
key={idx}
bankInfo={extendedBankInfo}
nativeSolBalance={nativeSolBalance}
isInLendingMode={tabActive === "lend"}
marginfiAccount={selectedAccount}
reloadBanks={async () => {
if (!connection) return;
fetchMrgnlendState({ marginfiConfig: config.mfiConfig, connection, wallet });
}}
marginfiClient={marginfiClient}
></PoolCard>
))
) : (
<Text style={tw`text-sm text-secondary pl-12px`}>No Isolated Pools Found</Text>
)
) : (
<Text style={tw`text-sm text-secondary pl-12px`}>No Isolated Pools Found</Text>
)
) : (
<PoolCardSkeleton />
)}
<PoolCardSkeleton />
)}
</View>
</View>
</View>
</Screen>
Expand Down

0 comments on commit cd4dadd

Please sign in to comment.