MP-3362: added Toaster explorer link (#430)
This commit is contained in:
parent
5bb87b6d27
commit
74e7c7e6a9
@ -2,13 +2,16 @@ import classNames from 'classnames'
|
|||||||
import { toast as createToast, Slide, ToastContainer } from 'react-toastify'
|
import { toast as createToast, Slide, ToastContainer } from 'react-toastify'
|
||||||
import { mutate } from 'swr'
|
import { mutate } from 'swr'
|
||||||
|
|
||||||
import { CheckCircled, Cross, CrossCircled } from 'components/Icons'
|
import { CheckCircled, Cross, CrossCircled, ExternalLink } from 'components/Icons'
|
||||||
import Text from 'components/Text'
|
import Text from 'components/Text'
|
||||||
import { DEFAULT_SETTINGS } from 'constants/defaultSettings'
|
import { DEFAULT_SETTINGS } from 'constants/defaultSettings'
|
||||||
|
import { EXPLORER_NAME, EXPLORER_TX_URL } from 'constants/explorer'
|
||||||
import { REDUCE_MOTION_KEY } from 'constants/localStore'
|
import { REDUCE_MOTION_KEY } from 'constants/localStore'
|
||||||
import useLocalStorage from 'hooks/useLocalStorage'
|
import useLocalStorage from 'hooks/useLocalStorage'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
|
|
||||||
|
import { TextLink } from './TextLink'
|
||||||
|
|
||||||
export default function Toaster() {
|
export default function Toaster() {
|
||||||
const [reduceMotion] = useLocalStorage<boolean>(REDUCE_MOTION_KEY, DEFAULT_SETTINGS.reduceMotion)
|
const [reduceMotion] = useLocalStorage<boolean>(REDUCE_MOTION_KEY, DEFAULT_SETTINGS.reduceMotion)
|
||||||
const toast = useStore((s) => s.toast)
|
const toast = useStore((s) => s.toast)
|
||||||
@ -23,9 +26,9 @@ export default function Toaster() {
|
|||||||
isError ? 'bg-error-bg/20' : 'bg-success-bg/20',
|
isError ? 'bg-error-bg/20' : 'bg-success-bg/20',
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className='mb-4 flex w-full gap-2'>
|
<div className='flex w-full gap-2 mb-4'>
|
||||||
<div className={classNames('rounded-sm p-1.5', isError ? 'bg-error' : 'bg-success')}>
|
<div className={classNames('rounded-sm p-1.5', isError ? 'bg-error' : 'bg-success')}>
|
||||||
<span className='block h-4 w-4 text-white'>
|
<span className='block w-4 h-4 text-white'>
|
||||||
{isError ? <CrossCircled /> : <CheckCircled />}
|
{isError ? <CrossCircled /> : <CheckCircled />}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@ -42,6 +45,20 @@ export default function Toaster() {
|
|||||||
<Text size='sm' className='font-bold text-white'>
|
<Text size='sm' className='font-bold text-white'>
|
||||||
{toast.message}
|
{toast.message}
|
||||||
</Text>
|
</Text>
|
||||||
|
{toast.hash && (
|
||||||
|
<TextLink
|
||||||
|
href={`${EXPLORER_TX_URL}${toast.hash}`}
|
||||||
|
target='_blank'
|
||||||
|
className={classNames(
|
||||||
|
'leading-4 underline mt-4 hover:no-underline hover:text-white',
|
||||||
|
isError ? 'text-error' : 'text-success',
|
||||||
|
)}
|
||||||
|
title={`View on ${EXPLORER_NAME}`}
|
||||||
|
>
|
||||||
|
{`View on ${EXPLORER_NAME}`}
|
||||||
|
<ExternalLink className='-mt-0.5 ml-2 inline w-3.5' />
|
||||||
|
</TextLink>
|
||||||
|
)}
|
||||||
<div className='absolute right-6 top-8 '>
|
<div className='absolute right-6 top-8 '>
|
||||||
<Cross className={classNames('h-2 w-2', isError ? 'text-error' : 'text-success')} />
|
<Cross className={classNames('h-2 w-2', isError ? 'text-error' : 'text-success')} />
|
||||||
</div>
|
</div>
|
||||||
@ -69,7 +86,7 @@ export default function Toaster() {
|
|||||||
transition={reduceMotion ? undefined : Slide}
|
transition={reduceMotion ? undefined : Slide}
|
||||||
className='p-0'
|
className='p-0'
|
||||||
toastClassName='top-[73px] z-20 m-0 mb-4 flex w-full bg-transparent p-0'
|
toastClassName='top-[73px] z-20 m-0 mb-4 flex w-full bg-transparent p-0'
|
||||||
bodyClassName='p-0 m-0 w-full flex'
|
bodyClassName='p-0 m-0 w-full flex -z-1'
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -172,6 +172,7 @@ export default function SwapForm(props: Props) {
|
|||||||
isMax: sellAssetAmount.isEqualTo(maxSellAmount),
|
isMax: sellAssetAmount.isEqualTo(maxSellAmount),
|
||||||
})
|
})
|
||||||
}, [
|
}, [
|
||||||
|
removedLends,
|
||||||
account?.id,
|
account?.id,
|
||||||
buyAsset.denom,
|
buyAsset.denom,
|
||||||
sellSideMarginThreshold,
|
sellSideMarginThreshold,
|
||||||
@ -306,4 +307,4 @@ export default function SwapForm(props: Props) {
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
6
src/constants/explorer.ts
Normal file
6
src/constants/explorer.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { IS_TESTNET } from 'constants/env'
|
||||||
|
|
||||||
|
export const EXPLORER_NAME = 'Mintscan'
|
||||||
|
export const EXPLORER_TX_URL = IS_TESTNET
|
||||||
|
? 'https://testnet.mintscan.io/osmosis-testnet/txs/'
|
||||||
|
: 'https://www.mintscan.io/osmosis/transactions/'
|
@ -20,7 +20,6 @@ import { formatAmountWithSymbol } from 'utils/formatters'
|
|||||||
import getTokenOutFromSwapResponse from 'utils/getTokenOutFromSwapResponse'
|
import getTokenOutFromSwapResponse from 'utils/getTokenOutFromSwapResponse'
|
||||||
import { BN } from 'utils/helpers'
|
import { BN } from 'utils/helpers'
|
||||||
|
|
||||||
|
|
||||||
function generateExecutionMessage(
|
function generateExecutionMessage(
|
||||||
sender: string | undefined = '',
|
sender: string | undefined = '',
|
||||||
contract: string,
|
contract: string,
|
||||||
@ -48,6 +47,7 @@ export default function createBroadcastSlice(
|
|||||||
set({
|
set({
|
||||||
toast: {
|
toast: {
|
||||||
message: successMessage,
|
message: successMessage,
|
||||||
|
hash: response.result.hash,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -56,6 +56,7 @@ export default function createBroadcastSlice(
|
|||||||
toast: {
|
toast: {
|
||||||
message: errorMessage ?? `Transaction failed: ${error}`,
|
message: errorMessage ?? `Transaction failed: ${error}`,
|
||||||
isError: true,
|
isError: true,
|
||||||
|
hash: response.result.hash,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -136,13 +137,17 @@ export default function createBroadcastSlice(
|
|||||||
if (response.result) {
|
if (response.result) {
|
||||||
set({ createAccountModal: false })
|
set({ createAccountModal: false })
|
||||||
const id = getSingleValueFromBroadcastResult(response.result, 'wasm', 'token_id')
|
const id = getSingleValueFromBroadcastResult(response.result, 'wasm', 'token_id')
|
||||||
set({ fundAccountModal: true, toast: { message: `Credit Account ${id} created` } })
|
set({
|
||||||
|
fundAccountModal: true,
|
||||||
|
toast: { message: `Credit Account ${id} created`, hash: response.result.hash },
|
||||||
|
})
|
||||||
return id
|
return id
|
||||||
} else {
|
} else {
|
||||||
set({
|
set({
|
||||||
createAccountModal: false,
|
createAccountModal: false,
|
||||||
toast: {
|
toast: {
|
||||||
message: response.error ?? `Transaction failed: ${response.error}`,
|
message: response.error ?? `Transaction failed: ${response.error}`,
|
||||||
|
hash: response.result.hash,
|
||||||
isError: true,
|
isError: true,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -529,4 +534,4 @@ export default function createBroadcastSlice(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4
src/types/interfaces/store/broadcast.d.ts
vendored
4
src/types/interfaces/store/broadcast.d.ts
vendored
@ -40,7 +40,7 @@ interface BroadcastSlice {
|
|||||||
slippage: number
|
slippage: number
|
||||||
isMax?: boolean
|
isMax?: boolean
|
||||||
}) => ExecutableTx
|
}) => ExecutableTx
|
||||||
toast: { message: string; isError?: boolean; title?: string } | null
|
toast: { message: string; isError?: boolean; title?: string; hash?: string } | null
|
||||||
unlock: (options: {
|
unlock: (options: {
|
||||||
accountId: string
|
accountId: string
|
||||||
vault: DepositedVault
|
vault: DepositedVault
|
||||||
@ -53,4 +53,4 @@ interface BroadcastSlice {
|
|||||||
borrow: BNCoin[]
|
borrow: BNCoin[]
|
||||||
reclaims: ActionCoin[]
|
reclaims: ActionCoin[]
|
||||||
}) => Promise<boolean>
|
}) => Promise<boolean>
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user