Skip to content

Commit

Permalink
Merge branch 'develop' into 226-swap-input-switcher
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikola Grujicic authored and Nikola Grujicic committed Dec 22, 2023
2 parents e18acef + c55d55d commit 433143b
Show file tree
Hide file tree
Showing 14 changed files with 296 additions and 20 deletions.
1 change: 1 addition & 0 deletions src/app/types/enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export enum ActionType {
SET_ASSET_LOADING = "SET_ASSET_LOADING",
SET_TOKEN_CAN_NOT_CREATE_WARNING_POOLS = "SET_TOKEN_CAN_NOT_CREATE_WARNING_POOLS",
SET_TOKEN_CAN_NOT_CREATE_WARNING_SWAP = "SET_TOKEN_CAN_NOT_CREATE_WARNING_SWAP",
SET_BLOCK_HASH_FINALIZED = "SET_BLOCK_HASH_FINALIZED",
}

export enum TokenSelection {
Expand Down
4 changes: 4 additions & 0 deletions src/assets/img/open-link-arrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file removed src/components/molecule/.gitkeep
Empty file.
41 changes: 39 additions & 2 deletions src/components/organism/AddPoolLiquidity/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import TokenAmountInput from "../../molecule/TokenAmountInput";
import CreatePool from "../CreatePool";
import PoolSelectTokenModal from "../PoolSelectTokenModal";
import SwapAndPoolSuccessModal from "../SwapAndPoolSuccessModal";
import ReviewTransactionModal from "../ReviewTransactionModal";

type AssetTokenProps = {
tokenSymbol: string;
Expand Down Expand Up @@ -94,6 +95,7 @@ const AddPoolLiquidity = ({ tokenBId }: AddPoolLiquidityProps) => {
const [inputEdited, setInputEdited] = useState<InputEditedProps>({ inputType: InputEditedType.exactIn });
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
const [poolExists, setPoolExists] = useState<boolean>(false);
const [reviewModalOpen, setReviewModalOpen] = useState<boolean>(false);
const [tooManyDecimalsError, setTooManyDecimalsError] = useState<TokenDecimalsErrorProps>({
tokenSymbol: "",
isError: false,
Expand Down Expand Up @@ -137,6 +139,7 @@ const AddPoolLiquidity = ({ tokenBId }: AddPoolLiquidityProps) => {
};

const handlePool = async () => {
setReviewModalOpen(false);
if (waitingForTransaction) {
clearTimeout(waitingForTransaction);
}
Expand Down Expand Up @@ -643,12 +646,46 @@ const AddPoolLiquidity = ({ tokenBId }: AddPoolLiquidityProps) => {
</>
)}
<Button
onClick={() => (getButtonProperties.disabled ? null : handlePool())}
onClick={() => (getButtonProperties.disabled ? null : setReviewModalOpen(true))}
variant={ButtonVariants.btnInteractivePink}
disabled={getButtonProperties.disabled || addLiquidityLoading}
>
{addLiquidityLoading ? <LottieMedium /> : getButtonProperties.label}
</Button>
<ReviewTransactionModal
open={reviewModalOpen}
title="Review adding liquidity"
priceImpact={priceImpact}
youPay={selectedTokenA.tokenBalance}
youReceive={selectedTokenB.assetTokenBalance}
tokenValueA={
inputEdited.inputType === InputEditedType.exactIn
? selectedTokenAssetValue?.tokenValue
: selectedTokenNativeValue?.tokenValue
}
tokenValueB={
inputEdited.inputType === InputEditedType.exactIn
? formatDecimalsFromToken(assetTokenWithSlippage?.tokenValue, selectedTokenB.decimals)
: formatDecimalsFromToken(nativeTokenWithSlippage?.tokenValue, selectedTokenA.nativeTokenDecimals)
}
tokenSymbolA={
inputEdited.inputType === InputEditedType.exactIn
? selectedTokenB.tokenSymbol
: selectedTokenA.nativeTokenSymbol
}
tokenSymbolB={
inputEdited.inputType === InputEditedType.exactIn
? selectedTokenB.tokenSymbol
: selectedTokenA.nativeTokenSymbol
}
onClose={() => {
setReviewModalOpen(false);
}}
inputType={inputEdited.inputType}
onConfirmTransaction={() => {
handlePool();
}}
/>
<PoolSelectTokenModal
onSelect={setSelectedTokenB}
onClose={() => setIsModalOpen(false)}
Expand Down Expand Up @@ -684,7 +721,7 @@ const AddPoolLiquidity = ({ tokenBId }: AddPoolLiquidityProps) => {
<WarningMessage show={isTokenCanNotCreateWarningPools} message={t("pageError.tokenCanNotCreateWarning")} />
<WarningMessage
show={isTransactionTimeout}
message={t("pageError.transactionTimeout", { url: `${assethubSubscanUrl}${selectedAccount.address}` })}
message={t("pageError.transactionTimeout", { url: `${assethubSubscanUrl}/account/${selectedAccount.address}` })}
/>
</div>
);
Expand Down
4 changes: 3 additions & 1 deletion src/components/organism/CreatePool/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,9 @@ const CreatePool = ({ tokenBSelected }: CreatePoolProps) => {
<WarningMessage show={isTokenCanNotCreateWarningPools} message={t("pageError.tokenCanNotCreateWarning")} />
<WarningMessage
show={isTransactionTimeout}
message={t("pageError.transactionTimeout", { url: `${assethubSubscanUrl}${selectedAccount.address}` })}
message={t("pageError.transactionTimeout", {
url: `${assethubSubscanUrl}/account/${selectedAccount.address}`,
})}
/>
</div>
)}
Expand Down
123 changes: 123 additions & 0 deletions src/components/organism/ReviewTransactionModal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import { FC } from "react";
import Modal from "../../atom/Modal";
import Button from "../../atom/Button";
import { ButtonVariants, InputEditedType } from "../../../app/types/enum";
import { ReactComponent as DotToken } from "../../../assets/img/dot-token.svg";

interface SwapSelectTokenModalProps {
open: boolean;
title: string;
youPay: string;
youReceive: string;
priceImpact: string;
tokenValueA?: string;
tokenValueB?: string;
tokenValueASecond?: string;
tokenValueBSecond?: string;
tokenSymbolA: string;
tokenSymbolB: string;
inputType: string;
showAll?: boolean;
onClose: () => void;
onConfirmTransaction: () => void;
}

const ReviewTransactionModal: FC<SwapSelectTokenModalProps> = ({
open,
title,
youPay,
youReceive,
priceImpact,
tokenValueA,
tokenValueASecond,
tokenValueB,
tokenValueBSecond,
tokenSymbolA,
tokenSymbolB,
inputType,
showAll,
onClose,
onConfirmTransaction,
}) => {
return (
<Modal isOpen={open} onClose={onClose} title={title}>
<div className="flex w-[360px] flex-col gap-5">
<div className="flex flex-col items-start">
<span className="font-inter text-small text-gray-200">You pay</span>
<span className="flex w-full items-center justify-between font-unbounded-variable text-heading-4 font-bold text-gray-400">
{youPay}
<DotToken />
</span>
</div>
<div className="flex flex-col items-start">
<span className="font-inter text-small text-gray-200">You receive</span>
<span className="flex w-full items-center justify-between font-unbounded-variable text-heading-4 font-bold text-gray-400">
{youReceive}
<DotToken />
</span>
</div>
<hr className="mb-0.5 mt-1 w-full border-[0.7px] border-gray-50" />
<div className="flex flex-col">
<div className="flex justify-between">
<span className="font-inter text-medium text-gray-300">Price impact</span>
<span className="font-inter text-medium text-gray-400">{priceImpact}%</span>
</div>
{showAll ? (
<>
<div className="flex justify-between">
<span className="font-inter text-medium text-gray-300">Expected output</span>
<span className="font-inter text-medium text-gray-400">
{tokenValueA} {tokenSymbolA}
</span>
</div>
<div className="flex justify-between">
<span className="font-inter text-medium text-gray-300">Minimum output</span>
<span className="font-inter text-medium text-gray-400">
{tokenValueB} {tokenSymbolA}
</span>
</div>
<div className="flex justify-between">
<span className="font-inter text-medium text-gray-300">Expected output</span>
<span className="font-inter text-medium text-gray-400">
{tokenValueASecond} {tokenSymbolB}
</span>
</div>
<div className="flex justify-between">
<span className="font-inter text-medium text-gray-300">Minimum output</span>
<span className="font-inter text-medium text-gray-400">
{tokenValueBSecond} {tokenSymbolB}
</span>
</div>
</>
) : (
<>
<div className="flex justify-between">
<span className="font-inter text-medium text-gray-300">
{inputType == InputEditedType.exactIn ? "Expected output" : "Expected input"}
</span>
<span className="font-inter text-medium text-gray-400">
{tokenValueA} {tokenSymbolA}
</span>
</div>
<div className="flex justify-between">
<span className="font-inter text-medium text-gray-300">
{inputType === InputEditedType.exactIn ? "Minimum output" : "Maximum input"}
</span>
<span className="font-inter text-medium text-gray-400">
{tokenValueB} {tokenSymbolB}
</span>
</div>
</>
)}
</div>
<div className="flex flex-col">
<Button onClick={onConfirmTransaction} variant={ButtonVariants.btnInteractivePink}>
Confirm Swap
</Button>
</div>
</div>
</Modal>
);
};

export default ReviewTransactionModal;
16 changes: 16 additions & 0 deletions src/components/organism/SwapAndPoolSuccessModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { FC } from "react";
import useGetNetwork from "../../../app/hooks/useGetNetwork";
import { ReactComponent as ArrowLeft } from "../../../assets/img/arrow-left.svg";
import { ReactComponent as ArrowRight } from "../../../assets/img/arrow-right.svg";
import { ReactComponent as OpenLinkArrow } from "../../../assets/img/open-link-arrow.svg";
import { useAppContext } from "../../../state";
import Modal from "../../atom/Modal";

interface SwapAndPoolSuccessModalProps {
Expand Down Expand Up @@ -28,6 +31,9 @@ const SwapAndPoolSuccessModal: FC<SwapAndPoolSuccessModalProps> = ({
tokenB,
onClose,
}) => {
const { assethubSubscanUrl, nativeTokenSymbol } = useGetNetwork();
const { state } = useAppContext();
const { blockHashFinalized } = state;
return (
<div>
<Modal isOpen={open} onClose={onClose}>
Expand All @@ -47,6 +53,16 @@ const SwapAndPoolSuccessModal: FC<SwapAndPoolSuccessModalProps> = ({
{tokenA.icon} {tokenA.value} {tokenA.symbol} <ArrowRight /> {tokenB.icon} {tokenB.value} {tokenB.symbol}
</div>
</div>
<div className="flex flex-row items-center justify-center gap-1 font-unbounded-variable text-medium underline">
<a
href={`${assethubSubscanUrl}/block${nativeTokenSymbol == "WND" ? "s" : ""}/${blockHashFinalized}`}
target="_blank"
rel="noreferrer"
>
View in block explorer
</a>
<OpenLinkArrow />
</div>
</div>
</Modal>
</div>
Expand Down
49 changes: 47 additions & 2 deletions src/components/organism/SwapTokens/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { useAppContext } from "../../../state";
import Button from "../../atom/Button";
import WarningMessage from "../../atom/WarningMessage";
import TokenAmountInput from "../../molecule/TokenAmountInput";
import ReviewTransactionModal from "../ReviewTransactionModal";
import SwapAndPoolSuccessModal from "../SwapAndPoolSuccessModal";
import SwapSelectTokenModal from "../SwapSelectTokenModal";

Expand Down Expand Up @@ -126,6 +127,7 @@ const SwapTokens = () => {
});

const [isTransactionTimeout, setIsTransactionTimeout] = useState<boolean>(false);
const [reviewModalOpen, setReviewModalOpen] = useState<boolean>(false);
const [waitingForTransaction, setWaitingForTransaction] = useState<NodeJS.Timeout>();
const [priceImpact, setPriceImpact] = useState<string>("");
const [assetBPriceOfOneAssetA, setAssetBPriceOfOneAssetA] = useState<string>("");
Expand Down Expand Up @@ -576,6 +578,7 @@ const SwapTokens = () => {
};

const handleSwap = async () => {
setReviewModalOpen(false);
if (waitingForTransaction) {
clearTimeout(waitingForTransaction);
}
Expand Down Expand Up @@ -1369,7 +1372,7 @@ const SwapTokens = () => {
/>

<Button
onClick={() => (getSwapButtonProperties.disabled ? null : handleSwap())}
onClick={() => (getSwapButtonProperties.disabled ? null : setReviewModalOpen(true))}
variant={ButtonVariants.btnInteractivePink}
disabled={getSwapButtonProperties.disabled || swapLoading}
>
Expand Down Expand Up @@ -1402,6 +1405,46 @@ const SwapTokens = () => {
}}
actionLabel="Swapped"
/>
<ReviewTransactionModal
open={reviewModalOpen}
title="Review Swap"
priceImpact={priceImpact}
youPay={selectedTokenAValue.tokenValue}
youReceive={selectedTokenBValue.tokenValue}
tokenValueA={
inputEdited.inputType === InputEditedType.exactIn
? selectedTokenBValue.tokenValue
: selectedTokenAValue.tokenValue
}
tokenValueB={
inputEdited.inputType === InputEditedType.exactIn
? formatDecimalsFromToken(
formatInputTokenValue(tokenBValueForSwap.tokenValue, selectedTokens.tokenB.decimals),
selectedTokens.tokenB.decimals
)
: formatDecimalsFromToken(
formatInputTokenValue(tokenAValueForSwap.tokenValue, selectedTokens.tokenA.decimals),
selectedTokens.tokenA.decimals
)
}
tokenSymbolA={
inputEdited.inputType === InputEditedType.exactIn
? selectedTokens.tokenB.tokenSymbol
: selectedTokens.tokenA.tokenSymbol
}
tokenSymbolB={
inputEdited.inputType === InputEditedType.exactIn
? selectedTokens.tokenB.tokenSymbol
: selectedTokens.tokenA.tokenSymbol
}
onClose={() => {
setReviewModalOpen(false);
}}
inputType={inputEdited.inputType}
onConfirmTransaction={() => {
handleSwap();
}}
/>
</div>
<WarningMessage show={lowTradingMinimum} message={t("pageError.tradingMinimum")} />
<WarningMessage
Expand All @@ -1422,7 +1465,9 @@ const SwapTokens = () => {
<WarningMessage show={isTokenCanNotCreateWarningSwap} message={t("pageError.tokenCanNotCreateWarning")} />
<WarningMessage
show={isTransactionTimeout}
message={t("pageError.transactionTimeout", { url: `${assethubSubscanUrl}${selectedAccount.address}` })}
message={t("pageError.transactionTimeout", {
url: `${assethubSubscanUrl}/account${nativeTokenSymbol == "WND" ? "s" : ""}/${selectedAccount.address}`,
})}
/>
</div>
);
Expand Down
Loading

0 comments on commit 433143b

Please sign in to comment.