Skip to content

Commit

Permalink
Fix reset of ledger loading state (#400)
Browse files Browse the repository at this point in the history
* Fix reset of ledger loading state
Display Advanced View in a dialog so that
sendTransaction mutation is not reset when this view is opened

* Disable allowance edit during sendTransaction submission

* SignTypedData: dialog for Advanced View
  • Loading branch information
everdimension authored Dec 30, 2023
1 parent 3e0ea3e commit 54b7e53
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export function AddressActionDetails({
singleAsset,
allowanceQuantityBase,
allowanceViewHref,
disabled = false,
}: {
recipientAddress?: string;
addressAction?: Pick<AnyAddressAction, 'label' | 'type'>;
Expand All @@ -29,6 +30,7 @@ export function AddressActionDetails({
singleAsset?: NonNullable<AddressAction['content']>['single_asset'];
allowanceQuantityBase?: string;
allowanceViewHref?: string;
disabled?: boolean;
}) {
return (
<>
Expand Down Expand Up @@ -62,6 +64,7 @@ export function AddressActionDetails({
singleAsset={singleAsset}
allowanceQuantityBase={allowanceQuantityBase}
allowanceViewHref={allowanceViewHref}
disabled={disabled}
/>
) : null}
</>
Expand Down
27 changes: 19 additions & 8 deletions src/ui/components/address-action/SingleAsset/SingleAsset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,15 @@ function FungibleAsset({
fungible,
quantity,
allowanceViewHref,
disabled,
}: {
address: string;
chain: Chain;
actionType: ActionType;
fungible: Asset;
quantity: string;
allowanceViewHref?: string;
disabled: boolean;
}) {
const commonQuantity = useMemo(
() =>
Expand Down Expand Up @@ -100,14 +102,20 @@ function FungibleAsset({
{actionType === 'approve' &&
Boolean(quantity) &&
allowanceViewHref ? (
<UIText
as={TextLink}
kind="small/accent"
style={{ color: 'var(--primary)' }}
to={allowanceViewHref}
>
Edit
</UIText>
disabled ? (
<UIText kind="small/accent" color="var(--neutral-500)">
Edit
</UIText>
) : (
<UIText
as={TextLink}
kind="small/accent"
color="var(--primary)"
to={allowanceViewHref}
>
Edit
</UIText>
)
) : null}
</HStack>
}
Expand Down Expand Up @@ -156,6 +164,7 @@ export function SingleAsset({
singleAsset,
allowanceQuantityBase,
allowanceViewHref,
disabled,
}: {
address: string;
chain: Chain;
Expand All @@ -165,6 +174,7 @@ export function SingleAsset({
>;
allowanceQuantityBase?: string;
allowanceViewHref?: string;
disabled: boolean;
}) {
const fungibleAsset = getFungibleAsset(singleAsset.asset);
const nftAsset = getNftAsset(singleAsset.asset);
Expand All @@ -183,6 +193,7 @@ export function SingleAsset({
fungible={fungibleAsset}
quantity={quantity}
allowanceViewHref={allowanceViewHref}
disabled={disabled}
/>
);
}
Expand Down
47 changes: 30 additions & 17 deletions src/ui/pages/SendTransaction/SendTransaction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ import { networksStore } from 'src/modules/networks/networks-store.client';
import type { PartiallyRequired } from 'src/shared/type-utils/PartiallyRequired';
import { useGasPrices } from 'src/ui/shared/requests/useGasPrices';
import { openInNewWindow } from 'src/ui/shared/openInNewWindow';
import { UnstyledLink } from 'src/ui/ui-kit/UnstyledLink';
import { setURLSearchParams } from 'src/ui/shared/setURLSearchParams';
import { InterpretLoadingState } from 'src/ui/components/InterpretLoadingState';
import { AddressActionDetails } from 'src/ui/components/address-action/AddressActionDetails';
Expand All @@ -64,6 +63,9 @@ import {
} from 'src/ui/components/SignTransactionButton';
import { INTERNAL_ORIGIN } from 'src/background/constants';
import { DelayedRender } from 'src/ui/components/DelayedRender';
import { CenteredDialog } from 'src/ui/ui-kit/ModalDialogs/CenteredDialog';
import type { HTMLDialogElementInterface } from 'src/ui/ui-kit/ModalDialogs/HTMLDialogElementInterface';
import { DialogTitle } from 'src/ui/ui-kit/ModalDialogs/DialogTitle';
import { TransactionConfiguration } from './TransactionConfiguration';
import {
DEFAULT_CONFIGURATION,
Expand Down Expand Up @@ -119,7 +121,6 @@ function usePreparedTx(transaction: IncomingTransaction, origin: string) {

enum View {
default = 'default',
advanced = 'advanced',
customAllowance = 'customAllowance',
}

Expand All @@ -135,6 +136,7 @@ function TransactionDefaultView({
interpretQuery,
incomingTransaction,
incomingTxWithGasAndFee,
onOpenAdvancedView,
onReject,
}: {
networks: Networks;
Expand All @@ -151,6 +153,7 @@ function TransactionDefaultView({
};
incomingTransaction: IncomingTransaction;
incomingTxWithGasAndFee?: IncomingTransactionWithChainId | null;
onOpenAdvancedView: () => void;
onReject: () => void;
}) {
const navigate = useNavigate();
Expand All @@ -161,11 +164,8 @@ function TransactionDefaultView({
const originForHref = useMemo(() => prepareForHref(origin), [origin]);

const { data: chainGasPrices } = useGasPrices(chain);
const [advancedViewHref, allowanceViewHref] = useMemo(
() =>
[View.advanced, View.customAllowance].map(
(view) => `?${setURLSearchParams(params, { view }).toString()}`
),
const allowanceViewHref = useMemo(
() => `?${setURLSearchParams(params, { view: View.customAllowance })}`,
[params]
);

Expand Down Expand Up @@ -278,6 +278,7 @@ function TransactionDefaultView({
singleAsset={singleAsset}
allowanceQuantityBase={allowanceQuantityBase}
allowanceViewHref={allowanceViewHref}
disabled={sendTransactionMutation.isLoading}
/>
{interpretQuery.isInitialLoading ? (
<InterpretLoadingState />
Expand All @@ -286,7 +287,7 @@ function TransactionDefaultView({
Unable to analyze the details of the transaction
</UIText>
) : null}
<Button kind="regular" as={UnstyledLink} to={advancedViewHref}>
<Button kind="regular" onClick={onOpenAdvancedView}>
Advanced View
</Button>
</VStack>
Expand Down Expand Up @@ -467,6 +468,10 @@ function SendTransactionContent({
const interpretAddressAction = interpretation?.action;

const view = params.get('view') || View.default;
const advancedDialogRef = useRef<HTMLDialogElementInterface | null>(null);
const openAdvancedView = useCallback(() => {
advancedDialogRef.current?.showModal();
}, []);

if (localAddressActionQuery.isSuccess && !localAddressAction) {
throw new Error('Unexpected missing localAddressAction');
Expand Down Expand Up @@ -516,18 +521,26 @@ function SendTransactionContent({
interpretQuery={interpretQuery}
incomingTransaction={incomingTransaction}
incomingTxWithGasAndFee={incomingTxWithGasAndFee}
onOpenAdvancedView={openAdvancedView}
onReject={handleReject}
/>
) : null}
{view === View.advanced ? (
<TransactionAdvancedView
networks={networks}
chain={chain}
interpretation={interpretation}
transaction={incomingTransaction}
transactionStringified={transactionStringified}
/>
) : null}
<CenteredDialog
ref={advancedDialogRef}
containerStyle={{ paddingBottom: 0 }}
renderWhenOpen={() => (
<>
<DialogTitle title="Advanced View" closeKind="icon" />
<TransactionAdvancedView
networks={networks}
chain={chain}
interpretation={interpretation}
transaction={incomingTransaction}
transactionStringified={transactionStringified}
/>
</>
)}
></CenteredDialog>
{view === View.customAllowance ? (
<CustomAllowanceView
address={wallet.address}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ import type { InterpretResponse } from 'src/modules/ethereum/transactions/types'
import { getInterpretationFunctionName } from 'src/modules/ethereum/transactions/interpret';
import { PageTop } from 'src/ui/components/PageTop';
import { TextLine } from 'src/ui/components/address-action/TextLine';
import { Content } from 'react-area';
import { Button } from 'src/ui/ui-kit/Button';
import { useCopyToClipboard } from 'src/ui/shared/useCopyToClipboard';
import { NavigationBar } from 'src/ui/components/NavigationBar';
import { valueToHex } from 'src/shared/units/valueToHex';
import { PageStickyFooter } from 'src/ui/components/PageStickyFooter';
import { PageBottom } from 'src/ui/components/PageBottom';

function maybeHexValue(value?: BigNumberish): string | null {
return value ? valueToHex(value) : null;
Expand Down Expand Up @@ -216,7 +216,6 @@ export function TransactionAdvancedView({

return (
<>
<NavigationBar title="Advanced View" />
<PageTop />
{transaction ? (
<TransactionDetails
Expand All @@ -226,7 +225,12 @@ export function TransactionAdvancedView({
interpretation={interpretation}
/>
) : null}
<Content name="sign-transaction-footer">
<Spacer height={8} />
<PageStickyFooter
style={{
marginInline: 'calc(-1 * var(--column-padding-inline))',
}}
>
<Spacer height={8} />
<Button
type="button"
Expand All @@ -246,7 +250,8 @@ export function TransactionAdvancedView({
})}
</HStack>
</Button>
</Content>
<PageBottom />
</PageStickyFooter>
</>
);
}
42 changes: 31 additions & 11 deletions src/ui/pages/SignTypedData/SignTypedData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import {
} from 'src/modules/ethereum/message-signing/prepareTypedData';
import type { Chain } from 'src/modules/networks/Chain';
import { useNetworks } from 'src/modules/networks/useNetworks';
import { UnstyledLink } from 'src/ui/ui-kit/UnstyledLink';
import { setURLSearchParams } from 'src/ui/shared/setURLSearchParams';
import { InterpretLoadingState } from 'src/ui/components/InterpretLoadingState';
import { AddressActionDetails } from 'src/ui/components/address-action/AddressActionDetails';
Expand All @@ -54,6 +53,9 @@ import { isDeviceAccount } from 'src/shared/types/validators';
import { NavigationTitle } from 'src/ui/components/NavigationTitle';
import { BUG_REPORT_BUTTON_HEIGHT } from 'src/ui/components/BugReportButton';
import { requestChainForOrigin } from 'src/ui/shared/requests/requestChainForOrigin';
import type { HTMLDialogElementInterface } from 'src/ui/ui-kit/ModalDialogs/HTMLDialogElementInterface';
import { CenteredDialog } from 'src/ui/ui-kit/ModalDialogs/CenteredDialog';
import { DialogTitle } from 'src/ui/ui-kit/ModalDialogs/DialogTitle';
import { HardwareSignMessage } from '../HardwareWalletConnection/HardwareSignMessage';
import { TypedDataAdvancedView } from './TypedDataAdvancedView';

Expand All @@ -75,7 +77,6 @@ export const TypedDataRow = React.forwardRef(

enum View {
default = 'default',
advanced = 'advanced',
customAllowance = 'customAllowance',
}

Expand Down Expand Up @@ -110,6 +111,7 @@ function TypedDataDefaultView({
allowanceQuantityBase,
onSignSuccess,
onReject,
onOpenAdvancedView,
}: {
origin: string;
wallet: ExternallyOwnedAccount;
Expand All @@ -126,6 +128,7 @@ function TypedDataDefaultView({
allowanceQuantityBase?: string;
onSignSuccess: (signature: string) => void;
onReject: () => void;
onOpenAdvancedView: () => void;
}) {
const [params] = useSearchParams();

Expand All @@ -147,11 +150,8 @@ function TypedDataDefaultView({

const originForHref = useMemo(() => prepareForHref(origin), [origin]);

const [advancedViewHref, allowanceViewHref] = useMemo(
() =>
[View.advanced, View.customAllowance].map(
(view) => `?${setURLSearchParams(params, { view }).toString()}`
),
const allowanceViewHref = useMemo(
() => `?${setURLSearchParams(params, { view: View.customAllowance })}`,
[params]
);

Expand Down Expand Up @@ -306,9 +306,12 @@ function TypedDataDefaultView({
singleAsset={addressAction?.content?.single_asset}
allowanceQuantityBase={allowanceQuantityBase || undefined}
allowanceViewHref={allowanceViewHref}
// TODO: create SignMessageButton (like SignTransactionButton)
// and set disabled state when sign mutation is loading (see SendTransaction.tsx)
// disabled={...}
/>
{typedDataFormatted ? (
<Button kind="regular" as={UnstyledLink} to={advancedViewHref}>
<Button kind="regular" onClick={onOpenAdvancedView}>
Advanced View
</Button>
) : null}
Expand Down Expand Up @@ -383,6 +386,10 @@ function SignTypedDataContent({
const [params] = useSearchParams();

const view = params.get('view') || View.default;
const advancedDialogRef = useRef<HTMLDialogElementInterface | null>(null);
const openAdvancedView = useCallback(() => {
advancedDialogRef.current?.showModal();
}, []);

const windowId = params.get('windowId');
invariant(windowId, 'windowId get-parameter is required');
Expand Down Expand Up @@ -474,12 +481,25 @@ function SignTypedDataContent({
allowanceQuantityBase || requestedAllowanceQuantityBase
}
onSignSuccess={handleSignSuccess}
onOpenAdvancedView={openAdvancedView}
onReject={handleReject}
/>
) : null}
{view === View.advanced && interpretation?.input ? (
<TypedDataAdvancedView data={interpretation.input} />
) : null}
<CenteredDialog
ref={advancedDialogRef}
containerStyle={{ paddingBottom: 0 }}
renderWhenOpen={() => (
<>
<DialogTitle
title={<UIText kind="body/accent">Advanced View</UIText>}
closeKind="icon"
/>
{interpretation?.input ? (
<TypedDataAdvancedView data={interpretation.input} />
) : null}
</>
)}
/>
{view === View.customAllowance ? (
<CustomAllowanceView
address={wallet.address}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react';
import { NavigationBar } from 'src/ui/components/NavigationBar';
import { TextLine } from 'src/ui/components/address-action/TextLine';
import { Surface } from 'src/ui/ui-kit/Surface';
import { VStack } from 'src/ui/ui-kit/VStack';
Expand All @@ -9,7 +8,6 @@ import { PageTop } from 'src/ui/components/PageTop';
export function TypedDataAdvancedView({ data }: { data: InterpretInput }) {
return (
<>
<NavigationBar title="Advanced View" />
<PageTop />
<Surface padding={16}>
<VStack gap={16}>
Expand Down
Loading

0 comments on commit 54b7e53

Please sign in to comment.