Skip to content
This repository was archived by the owner on Nov 10, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/logic/safe/store/actions/createTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import { Transaction, TransactionStatus, TxArgs } from 'src/logic/safe/store/mod
import { AnyAction } from 'redux'
import { PayableTx } from 'src/types/contracts/types.d'
import { AppReduxState } from 'src/store'
import { Dispatch } from './types'
import { Dispatch, DispatchReturn } from './types'

export const removeTxFromStore = (
tx: Transaction,
Expand Down Expand Up @@ -110,7 +110,7 @@ interface CreateTransactionArgs {
safeTxGas?: number
}

type CreateTransactionAction = ThunkAction<Promise<void>, AppReduxState, undefined, AnyAction>
type CreateTransactionAction = ThunkAction<Promise<void | string>, AppReduxState, DispatchReturn, AnyAction>
type ConfirmEventHandler = (safeTxHash: string) => void
type ErrorEventHandler = () => void

Expand All @@ -129,7 +129,7 @@ const createTransaction = (
}: CreateTransactionArgs,
onUserConfirm?: ConfirmEventHandler,
onError?: ErrorEventHandler,
): CreateTransactionAction => async (dispatch: Dispatch, getState: () => AppReduxState): Promise<void> => {
): CreateTransactionAction => async (dispatch: Dispatch, getState: () => AppReduxState): Promise<DispatchReturn> => {
const state = getState()

if (navigateToTransactionsTab) {
Expand Down
4 changes: 3 additions & 1 deletion src/logic/safe/store/actions/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ import { AnyAction } from 'redux'

import { AppReduxState } from 'src/store'

export type Dispatch = ThunkDispatch<AppReduxState, undefined, AnyAction>
export type DispatchReturn = string | undefined

export type Dispatch = ThunkDispatch<AppReduxState, DispatchReturn, AnyAction>
130 changes: 64 additions & 66 deletions src/routes/safe/components/Balances/Collectibles/index.tsx
Original file line number Diff line number Diff line change
@@ -1,85 +1,86 @@
import React, { useEffect } from 'react'
import Card from '@material-ui/core/Card'
import { makeStyles } from '@material-ui/core/styles'
import { createStyles, makeStyles } from '@material-ui/core/styles'
import { useSelector } from 'react-redux'

import Item from './components/Item'

import Paragraph from 'src/components/layout/Paragraph'
import { activeNftAssetsListSelector, nftTokensSelector } from 'src/logic/collectibles/store/selectors'
import SendModal from 'src/routes/safe/components/Balances/SendModal'
import { safeSelector } from 'src/logic/safe/store/selectors'
import { fontColor, lg, screenSm, screenXs } from 'src/theme/variables'
import { useAnalytics, SAFE_NAVIGATION_EVENT } from 'src/utils/googleAnalytics'
import { NFTToken } from 'src/logic/collectibles/sources/collectibles.d'

const useStyles = makeStyles({
cardInner: {
boxSizing: 'border-box',
maxWidth: '100%',
padding: '52px 54px',
},
cardOuter: {
boxShadow: '1px 2px 10px 0 rgba(212, 212, 211, 0.59)',
},
gridRow: {
boxSizing: 'border-box',
columnGap: '30px',
display: 'grid',
gridTemplateColumns: '1fr',
marginBottom: '45px',
maxWidth: '100%',
rowGap: '45px',

'&:last-child': {
marginBottom: '0',
const useStyles = makeStyles(
createStyles({
cardInner: {
boxSizing: 'border-box',
maxWidth: '100%',
padding: '52px 54px',
},

[`@media (min-width: ${screenXs}px)`]: {
gridTemplateColumns: '1fr 1fr',
cardOuter: {
boxShadow: '1px 2px 10px 0 rgba(212, 212, 211, 0.59)',
},
gridRow: {
boxSizing: 'border-box',
columnGap: '30px',
display: 'grid',
gridTemplateColumns: '1fr',
marginBottom: '45px',
maxWidth: '100%',
rowGap: '45px',

'&:last-child': {
marginBottom: '0',
},

[`@media (min-width: ${screenSm}px)`]: {
gridTemplateColumns: '1fr 1fr 1fr 1fr',
[`@media (min-width: ${screenXs}px)`]: {
gridTemplateColumns: '1fr 1fr',
},

[`@media (min-width: ${screenSm}px)`]: {
gridTemplateColumns: '1fr 1fr 1fr 1fr',
},
},
title: {
alignItems: 'center',
display: 'flex',
margin: '0 0 18px',
},
titleImg: {
backgroundPosition: '50% 50%',
backgroundRepeat: 'no-repeat',
backgroundSize: 'contain',
borderRadius: '50%',
height: '45px',
margin: '0 10px 0 0',
width: '45px',
},
titleText: {
color: fontColor,
fontSize: '18px',
fontWeight: 'normal',
lineHeight: '1.2',
margin: '0',
},
titleFiller: {
backgroundColor: '#e8e7e6',
flexGrow: 1,
height: '2px',
marginLeft: '40px',
},
noData: {
fontSize: lg,
textAlign: 'center',
},
},
title: {
alignItems: 'center',
display: 'flex',
margin: '0 0 18px',
},
titleImg: {
backgroundPosition: '50% 50%',
backgroundRepeat: 'no-repeat',
backgroundSize: 'contain',
borderRadius: '50%',
height: '45px',
margin: '0 10px 0 0',
width: '45px',
},
titleText: {
color: fontColor,
fontSize: '18px',
fontWeight: 'normal',
lineHeight: '1.2',
margin: '0',
},
titleFiller: {
backgroundColor: '#e8e7e6',
flexGrow: '1',
height: '2px',
marginLeft: '40px',
},
noData: {
fontSize: lg,
textAlign: 'center',
},
} as any)
}),
)

const Collectibles = (): React.ReactElement => {
const classes = useStyles()
const [selectedToken, setSelectedToken] = React.useState({})
const [selectedToken, setSelectedToken] = React.useState<NFTToken | undefined>()
const [sendNFTsModalOpen, setSendNFTsModalOpen] = React.useState(false)
const { address, ethBalance, name } = useSelector(safeSelector) || {}
const nftTokens = useSelector(nftTokensSelector)
const activeAssetsList = useSelector(activeNftAssetsListSelector)
const { trackEvent } = useAnalytics()
Expand All @@ -88,7 +89,7 @@ const Collectibles = (): React.ReactElement => {
trackEvent({ category: SAFE_NAVIGATION_EVENT, action: 'Collectibles' })
}, [trackEvent])

const handleItemSend = (nftToken) => {
const handleItemSend = (nftToken: NFTToken) => {
setSelectedToken(nftToken)
setSendNFTsModalOpen(true)
}
Expand Down Expand Up @@ -125,11 +126,8 @@ const Collectibles = (): React.ReactElement => {
</div>
<SendModal
activeScreenType="sendCollectible"
ethBalance={ethBalance}
isOpen={sendNFTsModalOpen}
onClose={() => setSendNFTsModalOpen(false)}
safeAddress={address}
safeName={name}
selectedToken={selectedToken}
/>
</Card>
Expand Down
48 changes: 37 additions & 11 deletions src/routes/safe/components/Balances/SendModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ import cn from 'classnames'
import React, { Suspense, useEffect, useState } from 'react'

import Modal from 'src/components/Modal'
import { CollectibleTx } from './screens/ReviewCollectible'
import { CustomTx } from './screens/ContractInteraction/ReviewCustomTx'
import { SendFundsTx } from './screens/SendFunds'
import { ContractInteractionTx } from './screens/ContractInteraction'
import { CustomTxProps } from './screens/ContractInteraction/SendCustomTx'
import { ReviewTxProp } from './screens/ReviewTx'
import { NFTToken } from 'src/logic/collectibles/sources/collectibles'
import { SendCollectibleTxInfo } from './screens/SendCollectible'

const ChooseTxType = React.lazy(() => import('./screens/ChooseTxType'))

Expand Down Expand Up @@ -39,10 +47,24 @@ const useStyles = makeStyles({
},
})

const SendModal = ({ activeScreenType, isOpen, onClose, recipientAddress, selectedToken }: any) => {
type Props = {
activeScreenType: string
isOpen: boolean
onClose: () => void
recipientAddress?: string
selectedToken?: string | NFTToken
}

const SendModal = ({
activeScreenType,
isOpen,
onClose,
recipientAddress,
selectedToken,
}: Props): React.ReactElement => {
const classes = useStyles()
const [activeScreen, setActiveScreen] = useState(activeScreenType || 'chooseTxType')
const [tx, setTx] = useState({})
const [tx, setTx] = useState<unknown>({})
const [isABI, setIsABI] = useState(true)

useEffect(() => {
Expand All @@ -53,7 +75,7 @@ const SendModal = ({ activeScreenType, isOpen, onClose, recipientAddress, select

const scalableModalSize = activeScreen === 'chooseTxType'

const handleTxCreation = (txInfo) => {
const handleTxCreation = (txInfo: SendCollectibleTxInfo) => {
setActiveScreen('reviewTx')
setTx(txInfo)
}
Expand Down Expand Up @@ -97,22 +119,22 @@ const SendModal = ({ activeScreenType, isOpen, onClose, recipientAddress, select
)}
{activeScreen === 'sendFunds' && (
<SendFunds
initialValues={tx}
initialValues={tx as SendFundsTx}
onClose={onClose}
onNext={handleTxCreation}
recipientAddress={recipientAddress}
selectedToken={selectedToken}
selectedToken={selectedToken as string}
/>
)}
{activeScreen === 'reviewTx' && (
<ReviewTx onClose={onClose} onPrev={() => setActiveScreen('sendFunds')} tx={tx} />
<ReviewTx onClose={onClose} onPrev={() => setActiveScreen('sendFunds')} tx={tx as ReviewTxProp} />
)}
{activeScreen === 'contractInteraction' && isABI && (
<ContractInteraction
isABI={isABI}
switchMethod={handleSwitchMethod}
contractAddress={recipientAddress}
initialValues={tx}
initialValues={tx as ContractInteractionTx}
onClose={onClose}
onNext={handleContractInteractionCreation}
/>
Expand All @@ -122,7 +144,7 @@ const SendModal = ({ activeScreenType, isOpen, onClose, recipientAddress, select
)}
{activeScreen === 'contractInteraction' && !isABI && (
<SendCustomTx
initialValues={tx}
initialValues={tx as CustomTxProps}
isABI={isABI}
switchMethod={handleSwitchMethod}
onClose={onClose}
Expand All @@ -131,19 +153,23 @@ const SendModal = ({ activeScreenType, isOpen, onClose, recipientAddress, select
/>
)}
{activeScreen === 'reviewCustomTx' && (
<ReviewCustomTx onClose={onClose} onPrev={() => setActiveScreen('contractInteraction')} tx={tx} />
<ReviewCustomTx onClose={onClose} onPrev={() => setActiveScreen('contractInteraction')} tx={tx as CustomTx} />
)}
{activeScreen === 'sendCollectible' && (
<SendCollectible
initialValues={tx}
onClose={onClose}
onNext={handleSendCollectible}
recipientAddress={recipientAddress}
selectedToken={selectedToken}
selectedToken={selectedToken as NFTToken}
/>
)}
{activeScreen === 'reviewCollectible' && (
<ReviewCollectible onClose={onClose} onPrev={() => setActiveScreen('sendCollectible')} tx={tx} />
<ReviewCollectible
onClose={onClose}
onPrev={() => setActiveScreen('sendCollectible')}
tx={tx as CollectibleTx}
/>
)}
</Suspense>
</Modal>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type ActiveScreen = 'sendFunds' | 'sendCollectible' | 'contractInteraction'

interface ChooseTxTypeProps {
onClose: () => void
recipientAddress: string
recipientAddress?: string
setActiveScreen: React.Dispatch<React.SetStateAction<ActiveScreen>>
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { makeStyles } from '@material-ui/core/styles'
import { useSnackbar } from 'notistack'
import React, { useEffect, useState } from 'react'
import { makeStyles } from '@material-ui/core/styles'
import { useDispatch, useSelector } from 'react-redux'
import { fromTokenUnit, toTokenUnit } from 'src/logic/tokens/utils/humanReadableValue'

import { getNetworkInfo } from 'src/config'
import { fromTokenUnit, toTokenUnit } from 'src/logic/tokens/utils/humanReadableValue'
import AddressInfo from 'src/components/AddressInfo'
import Block from 'src/components/layout/Block'
import Button from 'src/components/layout/Button'
Expand Down Expand Up @@ -43,7 +43,6 @@ type Props = {
const { nativeCoin } = getNetworkInfo()

const ContractInteractionReview = ({ onClose, onPrev, tx }: Props): React.ReactElement => {
const { enqueueSnackbar, closeSnackbar } = useSnackbar()
const classes = useStyles()
const dispatch = useDispatch()
const { address: safeAddress } = useSelector(safeSelector) || {}
Expand Down Expand Up @@ -74,18 +73,19 @@ const ContractInteractionReview = ({ onClose, onPrev, tx }: Props): React.ReactE
const txRecipient = tx.contractAddress
const txData = tx.data ? tx.data.trim() : ''
const txValue = tx.value ? toTokenUnit(tx.value, nativeCoin.decimals) : '0'
dispatch(
createTransaction({
safeAddress,
to: txRecipient,
valueInWei: txValue,
txData,
notifiedTransaction: TX_NOTIFICATION_TYPES.STANDARD_TX,
enqueueSnackbar,
closeSnackbar,
} as any),
)

if (safeAddress) {
dispatch(
createTransaction({
safeAddress,
to: txRecipient as string,
valueInWei: txValue,
txData,
notifiedTransaction: TX_NOTIFICATION_TYPES.STANDARD_TX,
}),
)
} else {
console.error('There was an error trying to submit the transaction, the safeAddress was not found')
}
onClose()
}

Expand Down
Loading