diff --git a/.github/workflows/qa-deploy.yaml b/.github/workflows/qa-deploy.yaml index 7573c3b4..7c105162 100644 --- a/.github/workflows/qa-deploy.yaml +++ b/.github/workflows/qa-deploy.yaml @@ -23,7 +23,7 @@ jobs: cicd: needs: [pre-check] if: contains(needs.pre-check.outputs.codeowners, github.event.comment.user.login) - timeout-minutes: 10 + timeout-minutes: 30 runs-on: ubuntu-latest steps: - uses: actions/github-script@v3 diff --git a/.github/workflows/release-server.yaml b/.github/workflows/release-server.yaml index 8032d5ff..a966cab6 100644 --- a/.github/workflows/release-server.yaml +++ b/.github/workflows/release-server.yaml @@ -28,7 +28,7 @@ jobs: cicd: needs: [pre-check] if: contains(needs.pre-check.outputs.codeowners, github.event.pull_request.merged_by.login) - timeout-minutes: 10 + timeout-minutes: 30 runs-on: ubuntu-latest steps: diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 24670d35..9ca3173e 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -30,7 +30,7 @@ jobs: cicd: needs: [pre-check] if: contains(needs.pre-check.outputs.codeowners, github.event.pull_request.merged_by.login) - timeout-minutes: 10 + timeout-minutes: 30 runs-on: ubuntu-latest steps: - name: Checkout code repository diff --git a/.release/.changeset/chilled-lizards-compare.md b/.release/.changeset/chilled-lizards-compare.md new file mode 100644 index 00000000..f14199cb --- /dev/null +++ b/.release/.changeset/chilled-lizards-compare.md @@ -0,0 +1,5 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +--- + +Update widget ui diff --git a/.release/.changeset/cyan-boxes-judge.md b/.release/.changeset/cyan-boxes-judge.md new file mode 100644 index 00000000..f14199cb --- /dev/null +++ b/.release/.changeset/cyan-boxes-judge.md @@ -0,0 +1,5 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +--- + +Update widget ui diff --git a/.release/.changeset/early-drinks-bathe.md b/.release/.changeset/early-drinks-bathe.md new file mode 100644 index 00000000..f14199cb --- /dev/null +++ b/.release/.changeset/early-drinks-bathe.md @@ -0,0 +1,5 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +--- + +Update widget ui diff --git a/.release/.changeset/fuzzy-houses-complain.md b/.release/.changeset/fuzzy-houses-complain.md new file mode 100644 index 00000000..f14199cb --- /dev/null +++ b/.release/.changeset/fuzzy-houses-complain.md @@ -0,0 +1,5 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +--- + +Update widget ui diff --git a/.release/.changeset/metal-steaks-drive.md b/.release/.changeset/metal-steaks-drive.md new file mode 100644 index 00000000..9fe5c3aa --- /dev/null +++ b/.release/.changeset/metal-steaks-drive.md @@ -0,0 +1,5 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +--- + +Fix input and checkbox style diff --git a/.release/.changeset/nice-boxes-taste.md b/.release/.changeset/nice-boxes-taste.md new file mode 100644 index 00000000..f14199cb --- /dev/null +++ b/.release/.changeset/nice-boxes-taste.md @@ -0,0 +1,5 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +--- + +Update widget ui diff --git a/.release/.changeset/polite-monkeys-share.md b/.release/.changeset/polite-monkeys-share.md new file mode 100644 index 00000000..65875796 --- /dev/null +++ b/.release/.changeset/polite-monkeys-share.md @@ -0,0 +1,5 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +--- + +Update unknown network title diff --git a/.release/.changeset/pre.json b/.release/.changeset/pre.json new file mode 100644 index 00000000..96ac34e2 --- /dev/null +++ b/.release/.changeset/pre.json @@ -0,0 +1,25 @@ +{ + "mode": "pre", + "tag": "alpha", + "initialVersions": { + "@bnb-chain/canonical-bridge-sdk": "0.1.2", + "@bnb-chain/canonical-bridge-widget": "0.1.4" + }, + "changesets": [ + "chilled-lizards-compare", + "cyan-boxes-judge", + "early-drinks-bathe", + "fuzzy-houses-complain", + "metal-steaks-drive", + "nice-boxes-taste", + "polite-monkeys-share", + "rare-grapes-act", + "rotten-nails-drop", + "sixty-scissors-protect", + "slimy-clocks-rule", + "swift-rivers-accept", + "swift-suits-worry", + "tasty-pianos-raise", + "tough-colts-compare" + ] +} diff --git a/.release/.changeset/rare-grapes-act.md b/.release/.changeset/rare-grapes-act.md new file mode 100644 index 00000000..ad2eb2a0 --- /dev/null +++ b/.release/.changeset/rare-grapes-act.md @@ -0,0 +1,5 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +--- + +Some ui updates & Header chain switch update diff --git a/.release/.changeset/rotten-nails-drop.md b/.release/.changeset/rotten-nails-drop.md new file mode 100644 index 00000000..f14199cb --- /dev/null +++ b/.release/.changeset/rotten-nails-drop.md @@ -0,0 +1,5 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +--- + +Update widget ui diff --git a/.release/.changeset/sixty-scissors-protect.md b/.release/.changeset/sixty-scissors-protect.md new file mode 100644 index 00000000..d809e188 --- /dev/null +++ b/.release/.changeset/sixty-scissors-protect.md @@ -0,0 +1,5 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +--- + +Update ui diff --git a/.release/.changeset/slimy-clocks-rule.md b/.release/.changeset/slimy-clocks-rule.md new file mode 100644 index 00000000..f14199cb --- /dev/null +++ b/.release/.changeset/slimy-clocks-rule.md @@ -0,0 +1,5 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +--- + +Update widget ui diff --git a/.release/.changeset/swift-rivers-accept.md b/.release/.changeset/swift-rivers-accept.md new file mode 100644 index 00000000..f14199cb --- /dev/null +++ b/.release/.changeset/swift-rivers-accept.md @@ -0,0 +1,5 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +--- + +Update widget ui diff --git a/.release/.changeset/swift-suits-worry.md b/.release/.changeset/swift-suits-worry.md new file mode 100644 index 00000000..f14199cb --- /dev/null +++ b/.release/.changeset/swift-suits-worry.md @@ -0,0 +1,5 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +--- + +Update widget ui diff --git a/.release/.changeset/tasty-pianos-raise.md b/.release/.changeset/tasty-pianos-raise.md new file mode 100644 index 00000000..f14199cb --- /dev/null +++ b/.release/.changeset/tasty-pianos-raise.md @@ -0,0 +1,5 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +--- + +Update widget ui diff --git a/.release/.changeset/tough-colts-compare.md b/.release/.changeset/tough-colts-compare.md new file mode 100644 index 00000000..f14199cb --- /dev/null +++ b/.release/.changeset/tough-colts-compare.md @@ -0,0 +1,5 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +--- + +Update widget ui diff --git a/apps/canonical-bridge-server/.eslintrc.js b/apps/canonical-bridge-server/.eslintrc.js index 1841b8bd..922ba5ef 100644 --- a/apps/canonical-bridge-server/.eslintrc.js +++ b/apps/canonical-bridge-server/.eslintrc.js @@ -14,9 +14,9 @@ module.exports = { }, ignorePatterns: ['.eslintrc.js'], rules: { + '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/interface-name-prefix': 'off', '@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', - '@typescript-eslint/no-explicit-any': 'off', }, }; diff --git a/packages/canonical-bridge-widget/CHANGELOG.md b/packages/canonical-bridge-widget/CHANGELOG.md index d67955a7..e3aea745 100644 --- a/packages/canonical-bridge-widget/CHANGELOG.md +++ b/packages/canonical-bridge-widget/CHANGELOG.md @@ -1,5 +1,83 @@ # @bnb-chain/canonical-bridge-widget +## 0.3.2-alpha.12 + +### Patch Changes + +- Update widget ui + +## 0.3.2-alpha.11 + +### Patch Changes + +- Update widget ui + +## 0.3.2-alpha.10 + +### Patch Changes + +- Update widget ui + +## 0.3.2-alpha.9 + +### Patch Changes + +- Update widget ui + +## 0.3.2-alpha.8 + +### Patch Changes + +- Update widget ui + +## 0.3.2-alpha.7 + +### Patch Changes + +- Update widget ui + +## 0.3.2-alpha.6 + +### Patch Changes + +- Update widget ui + +## 0.3.2-alpha.5 + +### Patch Changes + +- Update widget ui + +## 0.3.2-alpha.4 + +### Patch Changes + +- Update widget ui + +## 0.3.2-alpha.3 + +### Patch Changes + +- Update widget ui + +## 0.3.2-alpha.2 + +### Patch Changes + +- Update widget ui + +## 0.3.2-alpha.1 + +### Patch Changes + +- Fix input and checkbox style + +## 0.3.2-alpha.0 + +### Patch Changes + +- Update ui + ## 0.3.1 ### Patch Changes diff --git a/packages/canonical-bridge-widget/package.json b/packages/canonical-bridge-widget/package.json index f16871a6..e7c00864 100644 --- a/packages/canonical-bridge-widget/package.json +++ b/packages/canonical-bridge-widget/package.json @@ -1,6 +1,6 @@ { "name": "@bnb-chain/canonical-bridge-widget", - "version": "0.3.1", + "version": "0.3.2-alpha.12", "description": "canonical bridge widget", "author": "bnb-chain", "private": false, diff --git a/packages/canonical-bridge-widget/src/core/components/icons/ConfirmCheckIcon.tsx b/packages/canonical-bridge-widget/src/core/components/icons/ConfirmCheckIcon.tsx new file mode 100644 index 00000000..83260879 --- /dev/null +++ b/packages/canonical-bridge-widget/src/core/components/icons/ConfirmCheckIcon.tsx @@ -0,0 +1,45 @@ +import { Box, Icon, IconProps, useColorMode, useTheme } from '@bnb-chain/space'; + +export const UncheckedIcon = (props: IconProps) => { + return ( + + + + ); +}; + +export const CheckedIcon = (props: IconProps) => { + return ( + + + + ); +}; + +export const ToAccountCheckBox = (props: { onClick: () => void; isChecked: boolean }) => { + const { onClick, isChecked } = props; + const theme = useTheme(); + const { colorMode } = useColorMode(); + + return ( + + {isChecked ? ( + + ) : ( + + )} + + ); +}; diff --git a/packages/canonical-bridge-widget/src/core/components/icons/ExLinkIcon.tsx b/packages/canonical-bridge-widget/src/core/components/icons/ExLinkIcon.tsx index 9b25aee0..c34a1f3c 100644 --- a/packages/canonical-bridge-widget/src/core/components/icons/ExLinkIcon.tsx +++ b/packages/canonical-bridge-widget/src/core/components/icons/ExLinkIcon.tsx @@ -10,23 +10,10 @@ export function ExLinkIcon(props: IconProps) { fill="none" {...props} > - - - - - - + ); } diff --git a/packages/canonical-bridge-widget/src/core/components/icons/WarningIcon.tsx b/packages/canonical-bridge-widget/src/core/components/icons/WarningIcon.tsx new file mode 100644 index 00000000..994a1df5 --- /dev/null +++ b/packages/canonical-bridge-widget/src/core/components/icons/WarningIcon.tsx @@ -0,0 +1,15 @@ +import { Icon, IconProps } from '@bnb-chain/space'; + +export function WarningIcon(props: IconProps) { + return ( + + + + + + ); +} diff --git a/packages/canonical-bridge-widget/src/core/hooks/useDebounce.ts b/packages/canonical-bridge-widget/src/core/hooks/useDebounce.ts index f57dec06..1bb9dcca 100644 --- a/packages/canonical-bridge-widget/src/core/hooks/useDebounce.ts +++ b/packages/canonical-bridge-widget/src/core/hooks/useDebounce.ts @@ -1,7 +1,7 @@ import { useEffect, useRef, useState } from 'react'; export const useDebounce = (value: any, delay = 500) => { - const [debouncedValue, setDebouncedValue] = useState(''); + const [debouncedValue, setDebouncedValue] = useState(value); const timerRef = useRef(); useEffect(() => { diff --git a/packages/canonical-bridge-widget/src/core/locales/en.ts b/packages/canonical-bridge-widget/src/core/locales/en.ts index d5d4b72d..3fc37b62 100644 --- a/packages/canonical-bridge-widget/src/core/locales/en.ts +++ b/packages/canonical-bridge-widget/src/core/locales/en.ts @@ -57,7 +57,7 @@ export const en = { 'transfer.button.confirm': 'Send', 'transfer.button.approve': 'Approve', - 'transfer.button.switch-network': 'Switch Network', + 'transfer.button.switch-network': 'Switch Network in Wallet', 'transfer.button.wallet-connect': 'Connect Wallet', 'transfer.button.switch-wallet': 'Switch Wallet', @@ -96,6 +96,9 @@ export const en = { 'select-modal.destination.incompatible.tooltip': 'The token you’ve selected is incompatible with this network. Please select another token.', + 'wallet.network.switch-network': 'Please switch the network', + 'wallet.network.unknown-network': 'Unsupported Network', + 'wallet.network.unknown-network-mobile': 'Network', 'wallet.button.connect-wallet': 'Connect Wallet', 'wallet.network.wrong-network': 'Wrong network', 'wallet.error.switch-network': diff --git a/packages/canonical-bridge-widget/src/modules/aggregator/hooks/useDefaultSelectedInfo.ts b/packages/canonical-bridge-widget/src/modules/aggregator/hooks/useDefaultSelectedInfo.ts index 4199d278..4c200c98 100644 --- a/packages/canonical-bridge-widget/src/modules/aggregator/hooks/useDefaultSelectedInfo.ts +++ b/packages/canonical-bridge-widget/src/modules/aggregator/hooks/useDefaultSelectedInfo.ts @@ -1,6 +1,7 @@ import { useEffect } from 'react'; +import { useAccount } from 'wagmi'; -import { useAppDispatch } from '@/modules/store/StoreProvider'; +import { useAppDispatch, useAppSelector } from '@/modules/store/StoreProvider'; import { setSendValue } from '@/modules/transfer/action'; import { useSelection } from '@/modules/aggregator/hooks/useSelection'; import { useAggregator } from '@/modules/aggregator/components/AggregatorProvider'; @@ -9,12 +10,14 @@ export function useDefaultSelectedInfo() { const { isReady, defaultSelectedInfo } = useAggregator(); const { selectDefault } = useSelection(); const dispatch = useAppDispatch(); + const { chainId } = useAccount(); + const sendValue = useAppSelector((state) => state.transfer.sendValue); useEffect(() => { if (isReady) { selectDefault(defaultSelectedInfo); - dispatch(setSendValue(defaultSelectedInfo.amount)); + dispatch(setSendValue(sendValue || defaultSelectedInfo.amount)); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [isReady]); + }, [isReady, chainId]); } diff --git a/packages/canonical-bridge-widget/src/modules/aggregator/hooks/useSelection.ts b/packages/canonical-bridge-widget/src/modules/aggregator/hooks/useSelection.ts index f3aadaa4..a22a793a 100644 --- a/packages/canonical-bridge-widget/src/modules/aggregator/hooks/useSelection.ts +++ b/packages/canonical-bridge-widget/src/modules/aggregator/hooks/useSelection.ts @@ -1,4 +1,4 @@ -import { useChains } from 'wagmi'; +import { useChains, useAccount } from 'wagmi'; import { useCallback } from 'react'; import { useAggregator } from '@/modules/aggregator/components/AggregatorProvider'; @@ -18,7 +18,9 @@ import { useTronWeb } from '@/core/hooks/useTronWeb'; import { useCurrentWallet } from '@/modules/wallet/CurrentWalletProvider'; export function useSelection() { - const { getFromChains, getToChains, getTokens, getToToken, adapters } = useAggregator(); + const { chainId } = useAccount(); + const { getFromChains, getToChains, getTokens, getToToken, adapters, defaultSelectedInfo } = + useAggregator(); const fromChain = useAppSelector((state) => state.transfer.fromChain); const toChain = useAppSelector((state) => state.transfer.toChain); @@ -79,6 +81,38 @@ export function useSelection() { }); }; + const selectFromChain = async (tmpFromChain: IBridgeChain) => { + // After selecting fromChain, if toChain becomes incompatible, reselect the first compatible network in toChain list. + const toChains = getToChains({ + fromChainId: tmpFromChain.id, + }); + const tmpToChain = + toChains.find((c) => isChainOrTokenCompatible(c) && c.id === toChain?.id) ?? + toChains.find((c) => isChainOrTokenCompatible(c) && c.chainType !== 'link'); + + const tmpTokens = await getSortedTokens({ + chainType: tmpFromChain.chainType, + fromChainId: tmpFromChain.id, + tokens: getTokens({ + fromChainId: tmpFromChain.id, + toChainId: tmpToChain?.id, + }), + }); + + const newToken = + tmpTokens.find( + (t) => + isChainOrTokenCompatible(t) && + t.displaySymbol.toUpperCase() === selectedToken?.displaySymbol.toUpperCase(), + ) ?? tmpTokens.find((t) => isChainOrTokenCompatible(t)); + + updateSelectedInfo({ + tmpToken: newToken, + tmpFromChain, + tmpToChain, + }); + }; + return { async selectDefault({ fromChainId, @@ -94,6 +128,15 @@ export function useSelection() { bridgeTypes.map((item) => [item, { symbol: tokenSymbol }]), ) as any as IBridgeToken; + if (chainId && chainId !== defaultSelectedInfo.fromChainId) { + const fromChains = getFromChains({}); + const chain = fromChains.find((chain) => chain.id === chainId); + if (chain) { + selectFromChain(chain); + return; + } + } + const fromChains = getFromChains({ toChainId, token, @@ -123,44 +166,11 @@ export function useSelection() { token: newToken, }); }, - - async selectFromChain(tmpFromChain: IBridgeChain) { - // After selecting fromChain, if toChain becomes incompatible, reselect the first compatible network in toChain list. - const toChains = getToChains({ - fromChainId: tmpFromChain.id, - }); - const tmpToChain = - toChains.find((c) => isChainOrTokenCompatible(c) && c.id === toChain?.id) ?? - toChains.find((c) => isChainOrTokenCompatible(c) && c.chainType !== 'link'); - - const tmpTokens = await getSortedTokens({ - chainType: tmpFromChain.chainType, - fromChainId: tmpFromChain.id, - tokens: getTokens({ - fromChainId: tmpFromChain.id, - toChainId: tmpToChain?.id, - }), - }); - - const newToken = - tmpTokens.find( - (t) => - isChainOrTokenCompatible(t) && - t.displaySymbol.toUpperCase() === selectedToken?.displaySymbol.toUpperCase(), - ) ?? tmpTokens.find((t) => isChainOrTokenCompatible(t)); - - updateSelectedInfo({ - tmpToken: newToken, - tmpFromChain, - tmpToChain, - }); - }, - + selectFromChain, async selectToChain(tmpToChain: IBridgeChain) { const fromChainId = fromChain!.id; const tmpTokens = await getSortedTokens({ - chainType: fromChain?.chainType, fromChainId, tokens: getTokens({ fromChainId, diff --git a/packages/canonical-bridge-widget/src/modules/transfer/components/Button/SwitchNetworkButton.tsx b/packages/canonical-bridge-widget/src/modules/transfer/components/Button/SwitchNetworkButton.tsx index 258ccfb5..970ae716 100644 --- a/packages/canonical-bridge-widget/src/modules/transfer/components/Button/SwitchNetworkButton.tsx +++ b/packages/canonical-bridge-widget/src/modules/transfer/components/Button/SwitchNetworkButton.tsx @@ -1,10 +1,10 @@ -import { Button, useColorMode, useIntl, useTheme } from '@bnb-chain/space'; +import { Button, useColorMode, useIntl, useTheme, ButtonProps } from '@bnb-chain/space'; import { useAppSelector } from '@/modules/store/StoreProvider'; import { reportEvent } from '@/core/utils/gtm'; import { useCurrentWallet } from '@/modules/wallet/CurrentWalletProvider'; -export const SwitchNetworkButton = () => { +export const SwitchNetworkButton = (props: ButtonProps) => { const { formatMessage } = useIntl(); const fromChain = useAppSelector((state) => state.transfer.fromChain); @@ -36,6 +36,7 @@ export const SwitchNetworkButton = () => { }, }); }} + {...props} > {formatMessage({ id: 'transfer.button.switch-network' })} diff --git a/packages/canonical-bridge-widget/src/modules/transfer/components/Button/SwitchWalletButton.tsx b/packages/canonical-bridge-widget/src/modules/transfer/components/Button/SwitchWalletButton.tsx index bf7ab95b..f19ba1a3 100644 --- a/packages/canonical-bridge-widget/src/modules/transfer/components/Button/SwitchWalletButton.tsx +++ b/packages/canonical-bridge-widget/src/modules/transfer/components/Button/SwitchWalletButton.tsx @@ -1,10 +1,10 @@ -import { Button, useColorMode, useIntl, useTheme } from '@bnb-chain/space'; +import { Button, ButtonProps, useColorMode, useIntl, useTheme } from '@bnb-chain/space'; import { reportEvent } from '@/core/utils/gtm'; import { useCurrentWallet } from '@/modules/wallet/CurrentWalletProvider'; import { useAppSelector } from '@/modules/store/StoreProvider'; -export const SwitchWalletButton = () => { +export const SwitchWalletButton = (props: ButtonProps) => { const { formatMessage } = useIntl(); const { linkWallet } = useCurrentWallet(); @@ -36,6 +36,7 @@ export const SwitchWalletButton = () => { }, }); }} + {...props} > {formatMessage({ id: 'transfer.button.switch-wallet' })} diff --git a/packages/canonical-bridge-widget/src/modules/transfer/components/Button/WalletButtonWrapper.tsx b/packages/canonical-bridge-widget/src/modules/transfer/components/Button/WalletButtonWrapper.tsx index a231a1d2..56e585fd 100644 --- a/packages/canonical-bridge-widget/src/modules/transfer/components/Button/WalletButtonWrapper.tsx +++ b/packages/canonical-bridge-widget/src/modules/transfer/components/Button/WalletButtonWrapper.tsx @@ -1,22 +1,43 @@ -import { PropsWithChildren } from 'react'; +import { PropsWithChildren, useEffect, useMemo, useState } from 'react'; import { useAppSelector } from '@/modules/store/StoreProvider'; import { WalletConnectButton } from '@/modules/transfer/components/Button/WalletConnectButton'; import { SwitchNetworkButton } from '@/modules/transfer/components/Button/SwitchNetworkButton'; import { useCurrentWallet } from '@/modules/wallet/CurrentWalletProvider'; import { SwitchWalletButton } from '@/modules/transfer/components/Button/SwitchWalletButton'; +import { useDebounce } from '@/core/hooks/useDebounce'; export function WalletButtonWrapper(props: PropsWithChildren) { const { children } = props; const fromChain = useAppSelector((state) => state.transfer.fromChain); const { isConnected, chainId, walletType } = useCurrentWallet(); + const [delay, setDelay] = useState(false); - if (isConnected) { - if (walletType !== fromChain?.chainType) { + useEffect(() => { + setTimeout(() => setDelay(true), 3000); + }, []); + + const payload = useMemo(() => { + return { + _chainId: chainId, + _fromChainId: fromChain?.id, + _isConnected: isConnected, + _walletType: walletType, + _fromChainType: fromChain?.chainType, + }; + }, [chainId, fromChain?.id, isConnected, walletType, fromChain?.chainType]); + + const { _chainId, _fromChainId, _isConnected, _walletType, _fromChainType } = useDebounce( + payload, + delay ? 1200 : 0, + ); + + if (_isConnected) { + if (_walletType !== _fromChainType && _fromChainType) { return ; } else { - if (chainId !== fromChain.id) { + if (_chainId !== _fromChainId && _fromChainId) { return ; } return <>{children}; diff --git a/packages/canonical-bridge-widget/src/modules/transfer/components/FromSection/index.tsx b/packages/canonical-bridge-widget/src/modules/transfer/components/FromSection/index.tsx index c80b11ec..3f143046 100644 --- a/packages/canonical-bridge-widget/src/modules/transfer/components/FromSection/index.tsx +++ b/packages/canonical-bridge-widget/src/modules/transfer/components/FromSection/index.tsx @@ -1,12 +1,4 @@ -import { - Flex, - Typography, - useBreakpointValue, - useColorMode, - useDisclosure, - useIntl, - useTheme, -} from '@bnb-chain/space'; +import { Flex, Typography, useColorMode, useDisclosure, useIntl, useTheme } from '@bnb-chain/space'; import { SelectButton } from '@/modules/transfer/components/SelectButton'; import { useAppSelector } from '@/modules/store/StoreProvider'; @@ -16,7 +8,6 @@ import { SourceNetworkModal } from '@/modules/aggregator/components/SelectModal/ export function FromSection() { const { colorMode } = useColorMode(); const { isOpen, onClose, onOpen } = useDisclosure(); - const isBase = useBreakpointValue({ base: true, md: false }) ?? false; const { formatMessage } = useIntl(); const fromChain = useAppSelector((state) => state.transfer.fromChain); @@ -24,18 +15,20 @@ export function FromSection() { return ( - {isBase ? ( - - - {formatMessage({ id: 'from.section.title' })} - - - ) : null} + + + {formatMessage({ id: 'from.section.title' })} + + { const { formatMessage } = useIntl(); const { colorMode } = useColorMode(); const theme = useTheme(); - const isBase = useBreakpointValue({ base: true, md: false }) ?? false; return ( - {!isBase ? ( - <> - - - - {formatMessage({ id: 'from.section.title' })} - - - - - {formatMessage({ id: 'to.section.title' })} - - - {' '} - - ) : null} + + + + {formatMessage({ id: 'from.section.title' })} + + + + + {formatMessage({ id: 'to.section.title' })} + + + {' '} - + diff --git a/packages/canonical-bridge-widget/src/modules/transfer/components/ReceiveInfo/ReceiveLoading.tsx b/packages/canonical-bridge-widget/src/modules/transfer/components/ReceiveInfo/ReceiveLoading.tsx index f34820c6..3b2473f1 100644 --- a/packages/canonical-bridge-widget/src/modules/transfer/components/ReceiveInfo/ReceiveLoading.tsx +++ b/packages/canonical-bridge-widget/src/modules/transfer/components/ReceiveInfo/ReceiveLoading.tsx @@ -1,41 +1,45 @@ -import { Flex, Skeleton, SkeletonCircle, useBreakpointValue } from '@bnb-chain/space'; +import { Flex, Skeleton, SkeletonCircle } from '@bnb-chain/space'; export const ReceiveLoading = () => { - const isBase = useBreakpointValue({ base: true, lg: false }) ?? false; - - return !isBase ? ( - - - - - - - - - ) : ( - - - - - - - - - + return ( + <> + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + - - - + ); }; diff --git a/packages/canonical-bridge-widget/src/modules/transfer/components/ReceiveInfo/index.tsx b/packages/canonical-bridge-widget/src/modules/transfer/components/ReceiveInfo/index.tsx index 11ff1cf3..00aa317e 100644 --- a/packages/canonical-bridge-widget/src/modules/transfer/components/ReceiveInfo/index.tsx +++ b/packages/canonical-bridge-widget/src/modules/transfer/components/ReceiveInfo/index.tsx @@ -1,4 +1,4 @@ -import { Box, Flex, useBreakpointValue, useColorMode, useIntl, useTheme } from '@bnb-chain/space'; +import { Box, Flex, useColorMode, useIntl, useTheme, Collapse } from '@bnb-chain/space'; import { useEffect, useMemo } from 'react'; import { useAppDispatch, useAppSelector } from '@/modules/store/StoreProvider'; @@ -38,7 +38,6 @@ export const ReceiveInfo = ({ onOpen }: ReceiveInfoProps) => { const { formatMessage } = useIntl(); const { loadingBridgeFees } = useLoadingBridgeFees(); const dispatch = useAppDispatch(); - const isBase = useBreakpointValue({ base: true, lg: false }) ?? false; const transferActionInfo = useAppSelector((state) => state.transfer.transferActionInfo); const isGlobalFeeLoading = useAppSelector((state) => state.transfer.isGlobalFeeLoading); @@ -99,7 +98,6 @@ export const ReceiveInfo = ({ onOpen }: ReceiveInfoProps) => { useEffect(() => { // On mobile - if (!isBase) return; if (sendValue === debouncedSendValue) { dispatch(setTransferActionInfo(undefined)); if (!selectedToken || !Number(debouncedSendValue)) { @@ -115,19 +113,18 @@ export const ReceiveInfo = ({ onOpen }: ReceiveInfoProps) => { } else { dispatch(setIsGlobalFeeLoading(true)); } - }, [selectedToken, debouncedSendValue, dispatch, sendValue, loadingBridgeFees, isBase]); + }, [selectedToken, debouncedSendValue, dispatch, sendValue, loadingBridgeFees]); const isHideSection = useMemo(() => { // no receive amount and some routes are displayed + if (!Number(sendValue)) return true; if (isGlobalFeeLoading) return false; return ( - !Number(sendValue) || - (!isBase && - estimatedAmount && - !Object.values(estimatedAmount).every((element) => element === undefined) && - !receiveAmt) + estimatedAmount && + !Object.values(estimatedAmount).every((element) => element === undefined) && + !receiveAmt ); - }, [sendValue, estimatedAmount, isBase, receiveAmt, isGlobalFeeLoading]); + }, [sendValue, estimatedAmount, receiveAmt, isGlobalFeeLoading]); const isHideRouteButton = useMemo(() => { return ( @@ -135,61 +132,80 @@ export const ReceiveInfo = ({ onOpen }: ReceiveInfoProps) => { ); }, [estimatedAmount]); - return !isHideSection ? ( - - - - {formatMessage({ id: 'you.receive.title' })} - - {isBase && !isHideRouteButton ? : null} - - - {debouncedSendValue === sendValue ? ( - receiveAmt && !isGlobalFeeLoading ? ( - <> - {isBase && } - {isBase && } - {bridgeType && ( - - )} - - - - + + + + + {formatMessage({ id: 'you.receive.title' })} + + {!isHideRouteButton ? ( + + + + ) : null} + + + {debouncedSendValue === sendValue ? ( + receiveAmt && !isGlobalFeeLoading ? ( + <> + { + + + } - /> - - - ) : !receiveAmt && !isGlobalFeeLoading ? ( - - ) : ( - - ) - ) : ( - - )} - - - ) : null; + { + + + + } + {bridgeType && ( + + )} + + + + + + + ) : !receiveAmt && !isGlobalFeeLoading && !isHideSection ? ( + + ) : ( + + ) + ) : ( + + )} + + + + + ); }; diff --git a/packages/canonical-bridge-widget/src/modules/transfer/components/SelectButton/TokenSelectButton.tsx b/packages/canonical-bridge-widget/src/modules/transfer/components/SelectButton/TokenSelectButton.tsx index a7333056..271da271 100644 --- a/packages/canonical-bridge-widget/src/modules/transfer/components/SelectButton/TokenSelectButton.tsx +++ b/packages/canonical-bridge-widget/src/modules/transfer/components/SelectButton/TokenSelectButton.tsx @@ -31,9 +31,10 @@ export function TokenSelectButton(props: SelectButtonProps) { p={'4px 8px 4px 4px'} justifyContent={'space-between'} gap={'8px'} - background={theme.colors[colorMode].button.select.background.default} + transition={'all .15s'} + background={theme.colors[colorMode].layer[4].default} _hover={{ - background: theme.colors[colorMode].button.select.background.hover, + background: theme.colors[colorMode].layer[4].hover, }} color={theme.colors[colorMode].text.primary} {...restProps} diff --git a/packages/canonical-bridge-widget/src/modules/transfer/components/SelectButton/index.tsx b/packages/canonical-bridge-widget/src/modules/transfer/components/SelectButton/index.tsx index b3643ba2..c62d4d1a 100644 --- a/packages/canonical-bridge-widget/src/modules/transfer/components/SelectButton/index.tsx +++ b/packages/canonical-bridge-widget/src/modules/transfer/components/SelectButton/index.tsx @@ -56,7 +56,7 @@ export function SelectButton(props: SelectButtonProps) { }} > - {chain?.name ?? 'Select Network'} + {chain?.name ?? ''} diff --git a/packages/canonical-bridge-widget/src/modules/transfer/components/SendInput/MaxLink.tsx b/packages/canonical-bridge-widget/src/modules/transfer/components/SendInput/MaxLink.tsx index 507f1681..256c86e1 100644 --- a/packages/canonical-bridge-widget/src/modules/transfer/components/SendInput/MaxLink.tsx +++ b/packages/canonical-bridge-widget/src/modules/transfer/components/SendInput/MaxLink.tsx @@ -53,7 +53,7 @@ export const MaxLink: React.FC = () => { cursor={!!balance ? 'pointer' : 'auto'} fontSize={'12px'} fontWeight={500} - pb={`1px`} + lineHeight={'16px'} transitionDuration="normal" sx={{ '@media (hover:hover)': { diff --git a/packages/canonical-bridge-widget/src/modules/transfer/components/SendInput/index.tsx b/packages/canonical-bridge-widget/src/modules/transfer/components/SendInput/index.tsx index fcfa5c04..0510e973 100644 --- a/packages/canonical-bridge-widget/src/modules/transfer/components/SendInput/index.tsx +++ b/packages/canonical-bridge-widget/src/modules/transfer/components/SendInput/index.tsx @@ -1,5 +1,5 @@ import { Box, Flex, Input, useColorMode, useDisclosure, useIntl, useTheme } from '@bnb-chain/space'; -import { useRef, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { useAppDispatch, useAppSelector } from '@/modules/store/StoreProvider'; import { setSendValue } from '@/modules/transfer/action'; @@ -85,10 +85,21 @@ export const SendInput: React.FC = () => { }, DEBOUNCE_DELAY); }; + useEffect(() => { + if (isGlobalFeeLoading && sendValue === debouncedSendValue) { + setIsFocused(false); + } + }, [isGlobalFeeLoading, debouncedSendValue, sendValue]); + return ( - + {formatMessage({ id: 'you.send.title' })} diff --git a/packages/canonical-bridge-widget/src/modules/transfer/components/ToAccount/index.tsx b/packages/canonical-bridge-widget/src/modules/transfer/components/ToAccount/index.tsx index d35c00c5..29f1dabf 100644 --- a/packages/canonical-bridge-widget/src/modules/transfer/components/ToAccount/index.tsx +++ b/packages/canonical-bridge-widget/src/modules/transfer/components/ToAccount/index.tsx @@ -7,7 +7,6 @@ import { FlexProps, useIntl, InputGroup, - InputRightElement, } from '@bnb-chain/space'; import { ChangeEvent, useRef, useState } from 'react'; import { useEffect } from 'react'; @@ -15,11 +14,9 @@ import { useBytecode } from 'wagmi'; import { setIsToAddressChecked, setToAccount } from '@/modules/transfer/action'; import { useTronTransferInfo } from '@/modules/transfer/hooks/tron/useTronTransferInfo'; -import { ErrorIcon } from '@/core/components/icons/ErrorIcon'; -import { CorrectIcon } from '@/core/components/icons/CorrectIcon'; import { useAppDispatch, useAppSelector } from '@/modules/store/StoreProvider'; -import { ConfirmCheckbox } from '@/core/components/ConfirmCheckbox'; import { useTronContract } from '@/modules/aggregator/adapters/meson/hooks/useTronContract'; +import { ToAccountCheckBox } from '@/core/components/icons/ConfirmCheckIcon'; export function ToAccount(props: FlexProps) { const { colorMode } = useColorMode(); @@ -67,13 +64,13 @@ export function ToAccount(props: FlexProps) { const isInvalid = (!isAvailableAccount && !!toAccount.address) || isTronContract === true || !!evmBytecode; - const onCheckboxChange = (e: React.ChangeEvent) => { - if (e.target.checked === true) { - setIsChecked(true); - dispatch(setIsToAddressChecked(true)); - } else { + const toggleChecked = () => { + if (isChecked) { setIsChecked(false); dispatch(setIsToAddressChecked(false)); + } else { + setIsChecked(true); + dispatch(setIsToAddressChecked(true)); } }; @@ -123,12 +120,6 @@ export function ToAccount(props: FlexProps) { borderColor: theme.colors[colorMode].text.danger, }} /> - {(isInvalid || isAvailableAccount) && ( - - {isInvalid && } - {isAvailableAccount && !isInvalid && } - - )} {isInvalid && ( @@ -137,16 +128,10 @@ export function ToAccount(props: FlexProps) { )} - - {formatMessage({ id: 'to.section.confirm.text' })} - + + + {formatMessage({ id: 'to.section.confirm.text' })} + ); } diff --git a/packages/canonical-bridge-widget/src/modules/transfer/components/ToSection/index.tsx b/packages/canonical-bridge-widget/src/modules/transfer/components/ToSection/index.tsx index d37568b3..ad33a7c6 100644 --- a/packages/canonical-bridge-widget/src/modules/transfer/components/ToSection/index.tsx +++ b/packages/canonical-bridge-widget/src/modules/transfer/components/ToSection/index.tsx @@ -1,12 +1,4 @@ -import { - Flex, - Typography, - theme, - useBreakpointValue, - useColorMode, - useDisclosure, - useIntl, -} from '@bnb-chain/space'; +import { Flex, Typography, theme, useColorMode, useDisclosure, useIntl } from '@bnb-chain/space'; import { SelectButton } from '@/modules/transfer/components/SelectButton'; import { useAppSelector } from '@/modules/store/StoreProvider'; @@ -16,25 +8,26 @@ import { DestinationNetworkModal } from '@/modules/aggregator/components/SelectM export function ToSection() { const { isOpen, onClose, onOpen } = useDisclosure(); const { formatMessage } = useIntl(); - const isBase = useBreakpointValue({ base: true, md: false }) ?? false; const { colorMode } = useColorMode(); const toChain = useAppSelector((state) => state.transfer.toChain); return ( - {isBase ? ( - - - {formatMessage({ id: 'to.section.title' })} - - - ) : null} + + + {formatMessage({ id: 'to.section.title' })} + + { ? formatMessage({ id: 'route.no-found.desc' }) : formatMessage({ id: !isNoRoute ? 'route.adjust.desc' : 'route.no-found.desc' })} - {isBase && !isNoRoute && ( + {!isNoRoute && ( svg': { + verticalAlign: '-3px', + }, + }} {...otherProps} > diff --git a/packages/canonical-bridge-widget/src/modules/transfer/components/TransferOverview/RouteInfo/FeesInfo.tsx b/packages/canonical-bridge-widget/src/modules/transfer/components/TransferOverview/RouteInfo/FeesInfo.tsx index 9af5c0b3..1145390b 100644 --- a/packages/canonical-bridge-widget/src/modules/transfer/components/TransferOverview/RouteInfo/FeesInfo.tsx +++ b/packages/canonical-bridge-widget/src/modules/transfer/components/TransferOverview/RouteInfo/FeesInfo.tsx @@ -22,6 +22,11 @@ export const FeesInfo = ({ summary, breakdown, bridgeType, isError }: FeesInfoPr display={'inline-block'} lineHeight={'16px'} opacity={isError ? 0.5 : 1} + sx={{ + '>svg': { + verticalAlign: '-3px', + }, + }} > { const routeError = useAppSelector((state) => state.transfer.routeError); return routeError && routeError[bridgeType] ? ( - + svg': { + verticalAlign: '-3px', + }, + }} + > {routeError[bridgeType]} diff --git a/packages/canonical-bridge-widget/src/modules/transfer/components/TransferOverview/RouteInfo/RouteName/index.tsx b/packages/canonical-bridge-widget/src/modules/transfer/components/TransferOverview/RouteInfo/RouteName/index.tsx index 5598d3d0..deba3e0b 100644 --- a/packages/canonical-bridge-widget/src/modules/transfer/components/TransferOverview/RouteInfo/RouteName/index.tsx +++ b/packages/canonical-bridge-widget/src/modules/transfer/components/TransferOverview/RouteInfo/RouteName/index.tsx @@ -25,8 +25,15 @@ export const RouteName = React.memo( const receiveValue = getSortedReceiveAmount(); const bestTimeRoute = useGetBestTime(); const bestReturnRoute = getMaxValueKey(receiveValue); + return ( - + {bridgeType === 'cBridge' ? ( ) : bridgeType === 'deBridge' ? ( diff --git a/packages/canonical-bridge-widget/src/modules/transfer/components/TransferOverview/index.tsx b/packages/canonical-bridge-widget/src/modules/transfer/components/TransferOverview/index.tsx index f3df1d3f..d8fd7405 100644 --- a/packages/canonical-bridge-widget/src/modules/transfer/components/TransferOverview/index.tsx +++ b/packages/canonical-bridge-widget/src/modules/transfer/components/TransferOverview/index.tsx @@ -6,6 +6,7 @@ import { useColorMode, useIntl, useTheme, + Collapse, } from '@bnb-chain/space'; import { ReactNode, useEffect, useMemo } from 'react'; @@ -102,72 +103,80 @@ export function TransferOverview({ routeContentBottom }: { routeContentBottom?: const showRoute = selectedToken && !!Number(sendValue) && toTokenInfo && options && !!options?.length; + const loading = !options || !options?.length || isGlobalFeeLoading; + const content = ( + + + + {formatMessage({ id: 'route.title' })} + {!options.length || isGlobalFeeLoading ? ( + + ) : !isBase ? ( + + ) : null} + + + + + + + + + {options?.map((bridge: ReactNode) => bridge)} + + + + + ); + return ( - - {showRoute && ( - - - - {!isBase ? ( - - {formatMessage({ id: 'route.title' })} - {!options.length || isGlobalFeeLoading ? ( - - ) : !isBase ? ( - - ) : null} - - ) : null} - - {!options || !options?.length || isGlobalFeeLoading ? ( - - - - - - ) : ( - - {options?.map((bridge: ReactNode) => bridge)} - - )} - - + + + {!routeContentBottom ? ( + content + ) : ( + + + {content} + - - )} - {routeContentBottom ? routeContentBottom : null} + )} + {routeContentBottom ? routeContentBottom : null} + ); } diff --git a/packages/canonical-bridge-widget/src/modules/transfer/index.tsx b/packages/canonical-bridge-widget/src/modules/transfer/index.tsx index c2f4f39d..2b51d015 100644 --- a/packages/canonical-bridge-widget/src/modules/transfer/index.tsx +++ b/packages/canonical-bridge-widget/src/modules/transfer/index.tsx @@ -1,6 +1,7 @@ import { Box, Flex, + Typography, useBreakpointValue, useColorMode, useDisclosure, @@ -32,7 +33,6 @@ export function TransferWidget() { return ( {appearance.bridgeTitle && ( - {appearance.bridgeTitle} - + )} @@ -72,11 +72,12 @@ export function TransferWidget() { - {isBase ? routeContentBottom : null} + {routeContentBottom} - {!isBase ? ( + - ) : ( + + {isBase && ( state.transfer.fromChain); const { formatMessage } = useIntl(); + const thresholdRef = useRef(false); const theme = useTheme(); const { colorMode } = useColorMode(); - const { chain, chainId, linkWallet } = useCurrentWallet(); + const { chain, chainId, linkWallet, walletType } = useCurrentWallet(); const fromChains = useFromChains(); - const isWrongNetwork = !!fromChain && fromChain.id !== chainId; - const { chainConfigs } = useAggregator(); - const supportedChains = fromChains.filter( - (c) => chainConfigs.find((e) => c.id === e.id) && c.chainType !== 'link', + const supportedChains = fromChains.filter((c) => chainConfigs.find((e) => c.id === e.id)); + const bridgeChains = useFromChains(); + + useEffect(() => { + thresholdRef.current = true; + setTimeout(() => { + thresholdRef.current = false; + }, 1000); + }, [chainId]); + + const switchDropdown = (onClose: () => void) => ( + + + + + {formatMessage({ id: 'wallet.network.switch-network' })} + + + + + + + {fromChain!.name} + + + + + {walletType !== fromChain?.chainType ? ( + + ) : ( + + )} + + + ); - const iconUrl = supportedChains.find((e) => e.id === chainId)?.icon; if (!chain) { - return null; + if (!chainId || !fromChain) return null; + + return ( + + {({ isOpen, onClose }) => { + return ( + <> + + + + + {formatMessage({ id: 'wallet.network.unknown-network' })} + + + {formatMessage({ id: 'wallet.network.unknown-network-mobile' })} + + + + + {switchDropdown(onClose)} + + ); + }} + + ); } + const isWrongNetwork = !!fromChain && fromChain.id !== chain.id && !thresholdRef.current; + const iconUrl = bridgeChains.find((e) => e.id === chain.id)?.icon; + return ( - {({ isOpen }) => { + {({ isOpen, onClose }) => { return ( <> - - + + {isWrongNetwork ? ( + + ) : ( + + )} {chain.name} - {isWrongNetwork && ( - - {formatMessage({ id: 'wallet.network.wrong-network' })} - - )} - - {supportedChains.map((item) => { - const isSelected = chainId === item.id; - - return ( - { - linkWallet({ - targetChainType: item.chainType, - targetChainId: item.id, - }); - }} - > - - - {item.name} - - {isSelected && } - - ); - })} - + {isWrongNetwork ? ( + switchDropdown(onClose) + ) : ( + + {supportedChains.map((item) => { + const isSelected = chainId === item.id; + + return ( + { + if (item.chainType === 'link') { + openLink(item.externalBridgeUrl); + return; + } + linkWallet({ + targetChainType: item.chainType, + targetChainId: item.id, + }); + }} + > + + + {item.name} + + {item.chainType === 'link' && ( + + )} + {isSelected && } + + ); + })} + + )} ); }} diff --git a/packages/canonical-bridge-widget/src/modules/wallet/components/ProfileMenu/index.tsx b/packages/canonical-bridge-widget/src/modules/wallet/components/ProfileMenu/index.tsx index 33645d3c..ed5aabf9 100644 --- a/packages/canonical-bridge-widget/src/modules/wallet/components/ProfileMenu/index.tsx +++ b/packages/canonical-bridge-widget/src/modules/wallet/components/ProfileMenu/index.tsx @@ -1,4 +1,4 @@ -import { Box, Center, Flex, useColorMode, useIntl, useTheme } from '@bnb-chain/space'; +import { Box, Center, Flex, Typography, useColorMode, useIntl, useTheme } from '@bnb-chain/space'; import { DisconnectIcon } from '@bnb-chain/icons'; import { useWalletKit } from '@node-real/walletkit'; import { useMemo } from 'react'; @@ -10,6 +10,7 @@ import { Dropdown } from '@/modules/wallet/components/Dropdown/Dropdown'; import { DropdownButton } from '@/modules/wallet/components/Dropdown/DropdownButton'; import { DropdownList } from '@/modules/wallet/components/Dropdown/DropdownList'; import { useCurrentWallet } from '@/modules/wallet/CurrentWalletProvider'; +import { WalletIcon } from '@/core/components/icons/WalletIcon'; export const ProfileMenu = () => { const { formatMessage } = useIntl(); @@ -23,6 +24,7 @@ export const ProfileMenu = () => { {({ isOpen, onClose }) => ( <> { {walletIcon} )} - {formatAppAddress({ address })} + + + {formatAppAddress({ address })} + + @@ -130,7 +136,7 @@ function useWalletIcon() { if (selectedWallet) { const { transparent: transparentLogos } = selectedWallet.logos ?? {}; const transparentLogo = (transparentLogos as any)?.[colorMode] ?? transparentLogos; - return transparentLogo; + return transparentLogo || ; } return null;