Skip to content

Commit

Permalink
refactor: LowGasAlert errors on EVM
Browse files Browse the repository at this point in the history
  • Loading branch information
CremaFR committed Sep 9, 2024
1 parent 9abf63b commit e9fe4c5
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 55 deletions.
5 changes: 5 additions & 0 deletions .changeset/late-seals-buy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"ledger-live-desktop": minor
---

refactor: LowGasAlert to be consistent with all other errors
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React, { useCallback } from "react";
import { useHistory } from "react-router-dom";
import { useDispatch } from "react-redux";
import { setTrackingSource } from "~/renderer/analytics/TrackPage";
import { isCurrencySupported } from "~/renderer/screens/exchange/config";
import Alert from "~/renderer/components/Alert";
import { Account } from "@ledgerhq/types-live/lib/account";
import { Flex } from "@ledgerhq/react-ui";
import TranslatedError from "~/renderer/components/TranslatedError";

type LowGasAlertBuyMoreProps = {
account: Account;
handleRequestClose: () => void;
gasPriceError: Error | null;
trackingSource: string;
};

/**
* LowGasAlertBuyMore
*
* This component renders an alert message when the user has insufficient gas
* to complete a transaction.
* It also provides a call to action to buy more crypto,
* handling redirection to the exchange flow.
*
* Usage:
* <LowGasAlertBuyMore
* account={mainAccount}
* handleRequestClose={closeAllModal}
* gasPriceError={gasPriceError}
* trackingSource={"swap | send or whatever"}s
* />
*
* Note: The component only renders if the currency is supported for "buy" actions
* and if there's a valid error passed.
*/
const LowGasAlertBuyMore = ({
account,
handleRequestClose,
gasPriceError,
trackingSource,
}: LowGasAlertBuyMoreProps) => {
const history = useHistory();
const dispatch = useDispatch();

const onBuyClick = useCallback(() => {
dispatch(handleRequestClose());
setTrackingSource(trackingSource);
history.push({
pathname: "/exchange",
state: {
currency: account.currency.id,
account: account.id,
mode: "buy",
},
});
}, [account.currency.id, account.id, history, trackingSource]);

Check failure on line 57 in apps/ledger-live-desktop/src/renderer/families/evm/SendAmountFields/LowGasAlertBuyMore.tsx

View check run for this annotation

live-github-bot / @Desktop • Test App

react-hooks/exhaustive-deps

React Hook useCallback has missing dependencies: 'dispatch' and 'handleRequestClose'. Either include them or remove the dependency array. If 'handleRequestClose' changes too often, find the parent component that defines it and wrap that definition in useCallback.

Check failure on line 57 in apps/ledger-live-desktop/src/renderer/families/evm/SendAmountFields/LowGasAlertBuyMore.tsx

View check run for this annotation

live-github-bot / @Desktop • Test App

react-hooks/exhaustive-deps

React Hook useCallback has missing dependencies: 'dispatch' and 'handleRequestClose'. Either include them or remove the dependency array. If 'handleRequestClose' changes too often, find the parent component that defines it and wrap that definition in useCallback.

if (!isCurrencySupported("BUY", account.currency)) {
return null;
}

if (!gasPriceError) return null;
return (
<Flex onClick={onBuyClick}>
<Alert type="warning">
<TranslatedError error={gasPriceError} />
</Alert>
</Flex>
);
};

export default LowGasAlertBuyMore;
Original file line number Diff line number Diff line change
Expand Up @@ -12,36 +12,11 @@ import GasPriceField from "./GasPriceField";
import MaxFeeField from "./MaxFeeField";
import PriorityFeeField from "./PriorityFeeField";
import SelectFeeStrategy from "./SelectFeeStrategy";
import TranslatedError from "~/renderer/components/TranslatedError";
import Alert from "~/renderer/components/Alert";
import { Flex } from "@ledgerhq/react-ui";
import { closeAllModal } from "~/renderer/actions/modals";
import { setTrackingSource } from "~/renderer/analytics/TrackPage";
import { useDispatch } from "react-redux";
import { useHistory } from "react-router";

const Root: NonNullable<EvmFamily["sendAmountFields"]>["component"] = props => {
const { account, updateTransaction, transaction } = props;
const bridge: AccountBridge<EvmTransaction> = getAccountBridge(account);

const { errors } = props.status;
const { gasPrice: messageGas, amount: messageAmount } = errors;
const dispatch = useDispatch();
const history = useHistory();

const onBuyClick = useCallback(() => {
dispatch(closeAllModal());
setTrackingSource("send flow");
history.push({
pathname: "/exchange",
state: {
currency: account.currency.id,
account: account.id,
mode: "buy", // buy or sell
},
});
}, [account.currency.id, account.id, dispatch, history]);

const [gasOptions, error, loading] = useGasOptions({
currency: account.currency,
transaction,
Expand Down Expand Up @@ -111,13 +86,6 @@ const Root: NonNullable<EvmFamily["sendAmountFields"]>["component"] = props => {
<SelectFeeStrategy gasOptions={gasOptions} onClick={onFeeStrategyClick} {...props} />
</>
)}
{(messageGas || messageAmount) && (
<Flex onClick={onBuyClick}>
<Alert type="warning" data-testid="alert-insufficient-funds-warning">
<TranslatedError error={messageGas || messageAmount} />
</Alert>
</Flex>
)}
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import Button from "~/renderer/components/Button";
import CurrencyDownStatusAlert from "~/renderer/components/CurrencyDownStatusAlert";
import ErrorBanner from "~/renderer/components/ErrorBanner";
import SpendableBanner from "~/renderer/components/SpendableBanner";
import BuyButton from "~/renderer/components/BuyButton";
import Label from "~/renderer/components/Label";
import Input from "~/renderer/components/Input";
import { useSelector } from "react-redux";
Expand All @@ -20,6 +19,8 @@ import SendAmountFields from "../SendAmountFields";
import AmountField from "../fields/AmountField";
import { StepProps } from "../types";
import { getLLDCoinFamily } from "~/renderer/families";
import { closeAllModal } from "~/renderer/actions/modals";
import LowGasAlertBuyMore from "~/renderer/families/evm/SendAmountFields/LowGasAlertBuyMore";

const StepAmount = (props: StepProps) => {
const {
Expand Down Expand Up @@ -60,6 +61,8 @@ const StepAmount = (props: StepProps) => {
}, [specific.nft, transaction]);

if (!status) return null;
const { errors } = status;
const { gasPrice } = errors;

return (
<Box flow={4}>
Expand Down Expand Up @@ -114,6 +117,12 @@ const StepAmount = (props: StepProps) => {
bridgePending={bridgePending}
updateTransaction={updateTransaction}
/>
<LowGasAlertBuyMore
account={mainAccount}
handleRequestClose={closeAllModal}
gasPriceError={gasPrice}
trackingSource={"send flow"}
/>
</Fragment>
</Box>
);
Expand All @@ -132,16 +141,12 @@ export class StepAmountFooter extends PureComponent<StepProps> {
const isTerminated = mainAccount.currency.terminated;
const hasErrors = Object.keys(errors).length;
const canNext = !bridgePending && !hasErrors && !isTerminated;
const { maxPriorityFee: maxPriorityFeeError, maxFee: maxFeeError } = errors;

return (
<>
{!isNFTSend ? (
<AccountFooter parentAccount={parentAccount} account={account} status={status} />
) : null}
{maxPriorityFeeError || maxFeeError ? (
<BuyButton currency={mainAccount.currency} account={mainAccount} />
) : null}
<Button
id={"send-amount-continue-button"}
isLoading={bridgePending}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import TrackPage from "~/renderer/analytics/TrackPage";
import Box from "~/renderer/components/Box";
import Button from "~/renderer/components/Button";
import CurrencyDownStatusAlert from "~/renderer/components/CurrencyDownStatusAlert";
import BuyButton from "~/renderer/components/BuyButton";
import { NotEnoughGas } from "@ledgerhq/errors";
import Alert from "~/renderer/components/Alert";
import TranslatedError from "~/renderer/components/TranslatedError";
import AccountFooter from "../AccountFooter";
Expand Down Expand Up @@ -64,13 +62,9 @@ export class StepAmountFooter extends PureComponent<StepProps> {
const isTerminated = mainAccount.currency.terminated;
const hasErrors = Object.keys(errors).length;
const canNext = !bridgePending && !hasErrors && !isTerminated;
const { gasPrice } = errors;
return (
<>
<AccountFooter parentAccount={parentAccount} account={account} status={status} />
{gasPrice && gasPrice instanceof NotEnoughGas ? (
<BuyButton currency={mainAccount.currency} account={mainAccount} />
) : null}
<Button
id={"sign-transaction-amount-continue-button"}
isLoading={bridgePending}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@ import React, { useCallback, useState } from "react";
import Box from "~/renderer/components/Box";
import SendAmountFields from "~/renderer/modals/Send/SendAmountFields";
import { SwapTransactionType } from "@ledgerhq/live-common/exchange/swap/types";
import TrackPage from "~/renderer/analytics/TrackPage";
import TrackPage, { setTrackingSource } from "~/renderer/analytics/TrackPage";

Check failure on line 5 in apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FeesDrawerLiveApp/index.tsx

View check run for this annotation

live-github-bot / @Desktop • Test App

@typescript-eslint/no-unused-vars

'setTrackingSource' is defined but never used.

Check failure on line 5 in apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FeesDrawerLiveApp/index.tsx

View check run for this annotation

live-github-bot / @Desktop • Test App

@typescript-eslint/no-unused-vars

'setTrackingSource' is defined but never used.
import { useGetSwapTrackingProperties } from "../../utils/index";
import { Account, AccountLike, FeeStrategy } from "@ledgerhq/types-live";
import { t } from "i18next";
import { Transaction } from "@ledgerhq/live-common/generated/types";
import { Button, Divider } from "@ledgerhq/react-ui";
import { Button, Divider, Flex } from "@ledgerhq/react-ui";

Check failure on line 10 in apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FeesDrawerLiveApp/index.tsx

View check run for this annotation

live-github-bot / @Desktop • Test App

@typescript-eslint/no-unused-vars

'Flex' is defined but never used.

Check failure on line 10 in apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FeesDrawerLiveApp/index.tsx

View check run for this annotation

live-github-bot / @Desktop • Test App

@typescript-eslint/no-unused-vars

'Flex' is defined but never used.
import Alert from "~/renderer/components/Alert";

Check failure on line 11 in apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FeesDrawerLiveApp/index.tsx

View check run for this annotation

live-github-bot / @Desktop • Test App

@typescript-eslint/no-unused-vars

'Alert' is defined but never used.

Check failure on line 11 in apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FeesDrawerLiveApp/index.tsx

View check run for this annotation

live-github-bot / @Desktop • Test App

@typescript-eslint/no-unused-vars

'Alert' is defined but never used.
import { getAccountBridge } from "@ledgerhq/live-common/bridge/impl";
import TranslatedError from "~/renderer/components/TranslatedError";

Check failure on line 13 in apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FeesDrawerLiveApp/index.tsx

View check run for this annotation

live-github-bot / @Desktop • Test App

@typescript-eslint/no-unused-vars

'TranslatedError' is defined but never used.

Check failure on line 13 in apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FeesDrawerLiveApp/index.tsx

View check run for this annotation

live-github-bot / @Desktop • Test App

@typescript-eslint/no-unused-vars

'TranslatedError' is defined but never used.
import { useHistory } from "react-router";

Check failure on line 14 in apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FeesDrawerLiveApp/index.tsx

View check run for this annotation

live-github-bot / @Desktop • Test App

@typescript-eslint/no-unused-vars

'useHistory' is defined but never used.

Check failure on line 14 in apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FeesDrawerLiveApp/index.tsx

View check run for this annotation

live-github-bot / @Desktop • Test App

@typescript-eslint/no-unused-vars

'useHistory' is defined but never used.
import { getMainAccount } from "@ledgerhq/live-common/account/index";
import LowGasAlertBuyMore from "~/renderer/families/evm/SendAmountFields/LowGasAlertBuyMore";

type Props = {
setTransaction: SwapTransactionType["setTransaction"];
mainAccount: AccountLike;
account: AccountLike;
parentAccount: Account;
status: SwapTransactionType["status"];
disableSlowStrategy?: boolean;
Expand All @@ -23,7 +28,7 @@ type Props = {

export default function FeesDrawerLiveApp({
setTransaction,
mainAccount,
account,
parentAccount,
status,
provider,
Expand All @@ -36,15 +41,17 @@ export default function FeesDrawerLiveApp({
const [isOpen, setIsOpen] = useState(true);
const [transaction, setTransactionState] = useState(initialTransaction);
const [transactionStatus, setTransactionStatus] = useState(status);
const mainAccount = getMainAccount(account, parentAccount);

const bridge = getAccountBridge(mainAccount, parentAccount);
const { amount: amountError, gasPrice: gasPriceError } = transactionStatus.errors;

Check failure on line 47 in apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FeesDrawerLiveApp/index.tsx

View check run for this annotation

live-github-bot / @Desktop • Test App

@typescript-eslint/no-unused-vars

'amountError' is assigned a value but never used.

Check failure on line 47 in apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FeesDrawerLiveApp/index.tsx

View check run for this annotation

live-github-bot / @Desktop • Test App

@typescript-eslint/no-unused-vars

'amountError' is assigned a value but never used.

const handleSetTransaction = useCallback(
(transaction: Transaction) => {
const account = mainAccount.type === "TokenAccount" ? parentAccount : mainAccount;
bridge
.prepareTransaction(account, transaction)
.prepareTransaction(mainAccount, transaction)
.then(preparedTransaction =>
bridge.getTransactionStatus(account, preparedTransaction).then(status => {
bridge.getTransactionStatus(mainAccount, preparedTransaction).then(status => {
setTransactionStatus(status);
setTransactionState(preparedTransaction);
setTransaction(preparedTransaction);
Expand All @@ -59,13 +66,12 @@ export default function FeesDrawerLiveApp({

const handleUpdateTransaction = useCallback(
(updater: (arg0: Transaction) => Transaction) => {
const account = mainAccount.type === "TokenAccount" ? parentAccount : mainAccount;
setTransactionState(prevTransaction => {
let updatedTransaction = updater(prevTransaction);
bridge
.prepareTransaction(account, updatedTransaction)
.prepareTransaction(mainAccount, updatedTransaction)
.then(preparedTransaction =>
bridge.getTransactionStatus(account, preparedTransaction).then(status => {
bridge.getTransactionStatus(mainAccount, preparedTransaction).then(status => {
setTransactionStatus(status);
setTransaction(preparedTransaction);
updatedTransaction = preparedTransaction;
Expand Down Expand Up @@ -130,6 +136,12 @@ export default function FeesDrawerLiveApp({
}}
/>
)}
<LowGasAlertBuyMore
account={mainAccount}
handleRequestClose={() => handleRequestClose(false)}
gasPriceError={gasPriceError}
trackingSource={"swap flow"}
/>
</Box>
<Divider />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ const SwapWebView = ({
FeesDrawerLiveApp,
{
setTransaction,
mainAccount: fromAccount,
account: fromAccount,
parentAccount: fromParentAccount,
status: status,
provider: undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ const SwapWebView = ({ manifest, liveAppUnavailable }: SwapWebProps) => {
FeesDrawerLiveApp,
{
setTransaction,
mainAccount: fromAccount,
account: fromAccount,
parentAccount: fromParentAccount,
status: status,
provider: undefined,
Expand Down

0 comments on commit e9fe4c5

Please sign in to comment.