Skip to content

Commit

Permalink
feat: use loading state on all modal submit buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
woodenfurniture committed Oct 2, 2023
1 parent 7e70cf6 commit 3eeec67
Show file tree
Hide file tree
Showing 15 changed files with 232 additions and 115 deletions.
6 changes: 4 additions & 2 deletions src/plugins/walletConnectToDapps/components/Account.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Checkbox, Flex } from '@chakra-ui/react'
import type { AccountId } from '@shapeshiftoss/caip'
import type { FC } from 'react'
import { type FC, useCallback } from 'react'
import { MiddleEllipsis } from 'components/MiddleEllipsis/MiddleEllipsis'
import { RawText } from 'components/Text'
import { accountIdToLabel } from 'state/slices/portfolioSlice/utils'
Expand All @@ -13,8 +13,10 @@ interface IProps {
}

export const Account: FC<IProps> = ({ accountId, isSelected, toggleAccountId, accountNumber }) => {
const handleChange = useCallback(() => toggleAccountId(accountId), [accountId, toggleAccountId])

return (
<Checkbox isChecked={isSelected} onChange={() => toggleAccountId(accountId)} width='full'>
<Checkbox isChecked={isSelected} onChange={handleChange} width='full'>
<Flex gap={2} justifyContent='space-between'>
<RawText fontWeight='bold'>Account #{accountNumber}</RawText>
<MiddleEllipsis value={accountIdToLabel(accountId)} color='text.subtle' />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,22 @@ export const AccountSelectionByChainId: FC<IProps> = ({
}) => {
const translate = useTranslate()
const [allChecked, setAllChecked] = useState(false)
const translateKey = (key: string) => `plugins.walletConnectToDapps.modal.sessionProposal.${key}`
const translateKey = useCallback(
(key: string) => `plugins.walletConnectToDapps.modal.sessionProposal.${key}`,
[],
)
const filter = useMemo(() => ({ chainId }), [chainId])
const accountIdsByAccountNumberChainId = useAppSelector(s =>
selectPortfolioAccountsGroupedByNumberByChainId(s, filter),
)
const accountIds = Object.entries(accountIdsByAccountNumberChainId).flatMap(
([_, accountIds]) => accountIds,
const accountIds = useMemo(
() => Object.entries(accountIdsByAccountNumberChainId).flatMap(([_, accountIds]) => accountIds),
[accountIdsByAccountNumberChainId],
)
const selectedAccountIdsByChainId = accountIds.filter(accountId =>
selectedAccountIds.includes(accountId),

const selectedAccountIdsByChainId = useMemo(
() => accountIds.filter(accountId => selectedAccountIds.includes(accountId)),
[accountIds, selectedAccountIds],
)

const renderAccounts = useMemo(() => {
Expand Down
28 changes: 17 additions & 11 deletions src/plugins/walletConnectToDapps/components/ChainReferenceCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
import { Tag } from '@chakra-ui/tag'
import { AccountSelectionByChainId } from 'plugins/walletConnectToDapps/components/AccountSelectionByChainId'
import type { FC } from 'react'
import { useMemo } from 'react'
import { useCallback, useMemo } from 'react'
import { useTranslate } from 'react-polyglot'
import { AssetIcon } from 'components/AssetIcon'
import { Row } from 'components/Row/Row'
Expand All @@ -30,6 +30,10 @@ type ChainReferenceCardProps = {
toggleAccountId: (accountId: string) => void
}

const borderRadiusProp = { base: 'lg', md: 'xl' }
const pxProp = { base: 4, md: 4 }
const pProp = { base: 0, md: 0 }

export const ChainReferenceCard: FC<ChainReferenceCardProps> = ({
methods,
events,
Expand All @@ -42,7 +46,10 @@ export const ChainReferenceCard: FC<ChainReferenceCardProps> = ({
const translate = useTranslate()
const asset = useAppSelector(s => selectFeeAssetByChainId(s, chainId))
const borderColor = useColorModeValue('blackAlpha.100', 'whiteAlpha.200')
const translateKey = (key: string) => `plugins.walletConnectToDapps.modal.sessionProposal.${key}`
const translateKey = useCallback(
(key: string) => `plugins.walletConnectToDapps.modal.sessionProposal.${key}`,
[],
)

const renderEvents = useMemo(() => {
return events.map(event => (
Expand All @@ -59,21 +66,20 @@ export const ChainReferenceCard: FC<ChainReferenceCardProps> = ({
</Tag>
))
}, [methods])

const hoverBg = useColorModeValue('blackAlpha.50', 'whiteAlpha.50')
const hoverProp = useMemo(() => ({ bg: hoverBg }), [hoverBg])

return (
<Card
borderColor={borderColor}
overflow='hidden'
width='full'
borderRadius={{ base: 'lg', md: 'xl' }}
>
<Card borderColor={borderColor} overflow='hidden' width='full' borderRadius={borderRadiusProp}>
<CardHeader
px={{ base: 4, md: 4 }}
px={pxProp}
display='flex'
alignItems='center'
justifyContent='space-between'
onClick={onToggle}
cursor='pointer'
_hover={{ bg: useColorModeValue('blackAlpha.50', 'whiteAlpha.50') }}
_hover={hoverProp}
>
<Heading display='flex' alignItems='center' gap={2}>
<AssetIcon src={asset?.networkIcon ?? asset?.icon} size='xs' />
Expand All @@ -85,7 +91,7 @@ export const ChainReferenceCard: FC<ChainReferenceCardProps> = ({
</Flex>
</CardHeader>
<Collapse in={isOpen}>
<CardBody p={{ base: 0, md: 0 }} bg='whiteAlpha.50'>
<CardBody p={pProp} bg='whiteAlpha.50'>
<Stack spacing={0} divider={<Divider />}>
<Row gap={4} variant='gutter' py={3}>
<Row.Label>{translate(translateKey('methods'))}</Row.Label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { ModalCollapsableSection } from 'plugins/walletConnectToDapps/components
import { useGetAbi } from 'plugins/walletConnectToDapps/hooks/useGetAbi'
import type { EthSendTransactionCallRequest } from 'plugins/walletConnectToDapps/types'
import type { FC } from 'react'
import { Fragment, useMemo } from 'react'
import { Fragment, useCallback, useMemo } from 'react'
import { FaCode } from 'react-icons/fa'
import { Amount } from 'components/Amount/Amount'
import { MiddleEllipsis } from 'components/MiddleEllipsis/MiddleEllipsis'
Expand Down Expand Up @@ -45,35 +45,38 @@ export const ContractInteractionBreakdown: FC<ContractInteractionBreakdownProps>

const addressColor = useColorModeValue('blue.500', 'blue.200')

const renderAbiInput = (input: ParamType, index: number): JSX.Element => {
const inputValue = transaction?.args[index].toString()
switch (input.type) {
case 'bytes[]':
return <EncodedText value={inputValue} />
case 'address':
return (
<HStack>
<Box flex={1} fontFamily='monospace' fontSize='md'>
<MiddleEllipsis color={addressColor} value={inputValue} />
</Box>
<CopyButton value={inputValue} />
{feeAsset && (
<ExternalLinkButton
href={`${feeAsset.explorerAddressLink}${inputValue}`}
ariaLabel={inputValue}
/>
)}
</HStack>
)
case 'tuple':
default:
return (
<RawText fontWeight='normal' fontSize='md'>
{inputValue}
</RawText>
)
}
}
const renderAbiInput = useCallback(
(input: ParamType, index: number): JSX.Element => {
const inputValue = transaction?.args[index].toString()
switch (input.type) {
case 'bytes[]':
return <EncodedText value={inputValue} />
case 'address':
return (
<HStack>
<Box flex={1} fontFamily='monospace' fontSize='md'>
<MiddleEllipsis color={addressColor} value={inputValue} />
</Box>
<CopyButton value={inputValue} />
{feeAsset && (
<ExternalLinkButton
href={`${feeAsset.explorerAddressLink}${inputValue}`}
ariaLabel={inputValue}
/>
)}
</HStack>
)
case 'tuple':
default:
return (
<RawText fontWeight='normal' fontSize='md'>
{inputValue}
</RawText>
)
}
},
[addressColor, feeAsset, transaction?.args],
)

return (
<ModalCollapsableSection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,20 @@ import type {
} from 'plugins/walletConnectToDapps/types'
import { CosmosSigningMethod } from 'plugins/walletConnectToDapps/types'
import type { WalletConnectRequestModalProps } from 'plugins/walletConnectToDapps/WalletConnectModalManager'
import { type FC, useMemo } from 'react'
import { type FC, useCallback, useMemo, useState } from 'react'
import { useTranslate } from 'react-polyglot'
import { FoxIcon } from 'components/Icons/FoxIcon'
import { RawText, Text } from 'components/Text'
import { useWallet } from 'hooks/useWallet/useWallet'
import { selectFeeAssetByChainId } from 'state/slices/selectors'
import { useAppSelector } from 'state/store'

const disabledProp = { opacity: 0.5, cursor: 'not-allowed', userSelect: 'none' }

export const CosmosSignMessageConfirmationModal: FC<
WalletConnectRequestModalProps<CosmosSignDirectCallRequest | CosmosSignAminoCallRequest>
> = ({ onConfirm: handleConfirm, onReject: handleReject, state, topic }) => {
> = ({ onConfirm, onReject, state, topic }) => {
const [isLoading, setIsLoading] = useState<boolean>(false)
const { address, chainId } = useWalletConnectState(state)
const peerMetadata = state.sessionsByTopic[topic]?.peer.metadata

Expand All @@ -42,6 +45,18 @@ export const CosmosSignMessageConfirmationModal: FC<
const cardBg = useColorModeValue('white', 'gray.850')
const request = state.modalData.requestEvent?.params.request

const handleConfirm = useCallback(async () => {
setIsLoading(true)
await onConfirm()
setIsLoading(false)
}, [onConfirm])

const handleReject = useCallback(async () => {
setIsLoading(true)
await onReject()
setIsLoading(false)
}, [onReject])

const methodSpecificContent: JSX.Element | null = useMemo(() => {
if (request?.method === CosmosSigningMethod.COSMOS_SIGN_AMINO) {
const {
Expand Down Expand Up @@ -161,11 +176,19 @@ export const CosmosSignMessageConfirmationModal: FC<
colorScheme='blue'
type='submit'
onClick={handleConfirm}
isDisabled={true}
isDisabled={true} // coming soon
_disabled={disabledProp}
isLoading={isLoading}
>
{translate('plugins.walletConnectToDapps.modal.signMessage.comingSoon')}
</Button>
<Button size='lg' width='full' onClick={handleReject}>
<Button
size='lg'
width='full'
onClick={handleReject}
isDisabled={isLoading}
_disabled={disabledProp}
>
{translate('plugins.walletConnectToDapps.modal.signMessage.reject')}
</Button>
</VStack>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,20 @@ import type {
EthSignCallRequest,
} from 'plugins/walletConnectToDapps/types'
import type { WalletConnectRequestModalProps } from 'plugins/walletConnectToDapps/WalletConnectModalManager'
import type { FC } from 'react'
import { type FC, useCallback, useState } from 'react'
import { useTranslate } from 'react-polyglot'
import { FoxIcon } from 'components/Icons/FoxIcon'
import { RawText, Text } from 'components/Text'
import { useWallet } from 'hooks/useWallet/useWallet'
import { selectFeeAssetByChainId } from 'state/slices/selectors'
import { useAppSelector } from 'state/store'

const disabledProp = { opacity: 0.5, cursor: 'not-allowed', userSelect: 'none' }

export const EIP155SignMessageConfirmationModal: FC<
WalletConnectRequestModalProps<EthSignCallRequest | EthPersonalSignCallRequest>
> = ({ onConfirm: handleConfirm, onReject: handleReject, state, topic }) => {
> = ({ onConfirm, onReject, state, topic }) => {
const [isLoading, setIsLoading] = useState<boolean>(false)
const { address, message, chainId } = useWalletConnectState(state)
const peerMetadata = state.sessionsByTopic[topic]?.peer.metadata

Expand All @@ -40,6 +43,18 @@ export const EIP155SignMessageConfirmationModal: FC<
const WalletIcon = walletInfo?.icon ?? FoxIcon
const cardBg = useColorModeValue('white', 'gray.850')

const handleConfirm = useCallback(async () => {
setIsLoading(true)
await onConfirm()
setIsLoading(false)
}, [onConfirm])

const handleReject = useCallback(async () => {
setIsLoading(true)
await onReject()
setIsLoading(false)
}, [onReject])

if (!peerMetadata) return null

return (
Expand Down Expand Up @@ -79,10 +94,24 @@ export const EIP155SignMessageConfirmationModal: FC<
translation='plugins.walletConnectToDapps.modal.signMessage.description'
/>
<VStack spacing={4}>
<Button size='lg' width='full' colorScheme='blue' type='submit' onClick={handleConfirm}>
<Button
size='lg'
width='full'
colorScheme='blue'
type='submit'
onClick={handleConfirm}
_disabled={disabledProp}
isLoading={isLoading}
>
{translate('plugins.walletConnectToDapps.modal.signMessage.confirm')}
</Button>
<Button size='lg' width='full' onClick={handleReject}>
<Button
size='lg'
width='full'
onClick={handleReject}
isDisabled={isLoading}
_disabled={disabledProp}
>
{translate('plugins.walletConnectToDapps.modal.signMessage.reject')}
</Button>
</VStack>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { TypedMessageInfo } from 'plugins/walletConnectToDapps/components/modals
import { useWalletConnectState } from 'plugins/walletConnectToDapps/hooks/useWalletConnectState'
import type { EthSignTypedDataCallRequest } from 'plugins/walletConnectToDapps/types'
import type { WalletConnectRequestModalProps } from 'plugins/walletConnectToDapps/WalletConnectModalManager'
import type { FC } from 'react'
import { type FC, useCallback, useState } from 'react'
import { useTranslate } from 'react-polyglot'
import { FoxIcon } from 'components/Icons/FoxIcon'
import { Text } from 'components/Text'
Expand All @@ -14,9 +14,12 @@ import { assertIsDefined } from 'lib/utils'
import { selectFeeAssetByChainId } from 'state/slices/selectors'
import { useAppSelector } from 'state/store'

const disabledProp = { opacity: 0.5, cursor: 'not-allowed', userSelect: 'none' }

export const EIP155SignTypedDataConfirmation: FC<
WalletConnectRequestModalProps<EthSignTypedDataCallRequest>
> = ({ onConfirm: handleConfirm, onReject: handleReject, state }) => {
> = ({ onConfirm, onReject, state }) => {
const [isLoading, setIsLoading] = useState<boolean>(false)
const { address, message, chainId } = useWalletConnectState(state)
assertIsDefined(message)

Expand All @@ -28,6 +31,18 @@ export const EIP155SignTypedDataConfirmation: FC<
const walletInfo = useWallet().state.walletInfo
const WalletIcon = walletInfo?.icon ?? FoxIcon

const handleConfirm = useCallback(async () => {
setIsLoading(true)
await onConfirm()
setIsLoading(false)
}, [onConfirm])

const handleReject = useCallback(async () => {
setIsLoading(true)
await onReject()
setIsLoading(false)
}, [onReject])

return (
<>
<ModalSection title='plugins.walletConnectToDapps.modal.signMessage.signingFrom'>
Expand All @@ -44,10 +59,24 @@ export const EIP155SignTypedDataConfirmation: FC<
translation='plugins.walletConnectToDapps.modal.signMessage.description'
/>
<VStack spacing={4}>
<Button size='lg' width='full' colorScheme='blue' type='submit' onClick={handleConfirm}>
<Button
size='lg'
width='full'
colorScheme='blue'
type='submit'
onClick={handleConfirm}
_disabled={disabledProp}
isLoading={isLoading}
>
{translate('plugins.walletConnectToDapps.modal.signMessage.confirm')}
</Button>
<Button size='lg' width='full' onClick={handleReject}>
<Button
size='lg'
width='full'
onClick={handleReject}
isDisabled={isLoading}
_disabled={disabledProp}
>
{translate('plugins.walletConnectToDapps.modal.signMessage.reject')}
</Button>
</VStack>
Expand Down
Loading

0 comments on commit 3eeec67

Please sign in to comment.