From ee0d0a21cb9b912d52b28f9c6015d59157529428 Mon Sep 17 00:00:00 2001 From: homu-chain Date: Wed, 9 Dec 2020 12:36:10 +0800 Subject: [PATCH 1/5] feat: detecting device before rendering --- src/components/RippleSpinner/index.tsx | 11 ++++++++ src/components/RippleSpinner/ripple.css | 32 +++++++++++++++++++++ src/index-desktop.tsx | 30 ++++++++++++++++++++ src/index-mobile.tsx | 7 +++++ src/index.tsx | 37 ++++++++----------------- src/utils/user-agent.ts | 16 +++++++++++ 6 files changed, 108 insertions(+), 25 deletions(-) create mode 100644 src/components/RippleSpinner/index.tsx create mode 100644 src/components/RippleSpinner/ripple.css create mode 100644 src/index-desktop.tsx create mode 100644 src/index-mobile.tsx create mode 100644 src/utils/user-agent.ts diff --git a/src/components/RippleSpinner/index.tsx b/src/components/RippleSpinner/index.tsx new file mode 100644 index 0000000..e650679 --- /dev/null +++ b/src/components/RippleSpinner/index.tsx @@ -0,0 +1,11 @@ +import React from 'react' +import './ripple.css' + +export const RippleSpinner = () => { + return ( +
+
+
+
+ ) +} diff --git a/src/components/RippleSpinner/ripple.css b/src/components/RippleSpinner/ripple.css new file mode 100644 index 0000000..9550946 --- /dev/null +++ b/src/components/RippleSpinner/ripple.css @@ -0,0 +1,32 @@ +.lds-ripple { + display: inline-block; + position: relative; + width: 300px; + height: 300px; +} +.lds-ripple div { + position: absolute; + border: 4px solid #6b70e0; + opacity: 1; + border-radius: 50%; + animation: lds-ripple 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite; +} +.lds-ripple div:nth-child(2) { + animation-delay: -0.75s; +} +@keyframes lds-ripple { + 0% { + top: 142px; + left: 142px; + width: 0; + height: 0; + opacity: 1; + } + 100% { + top: 0px; + left: 0px; + width: 270px; + height: 270px; + opacity: 0; + } +} diff --git a/src/index-desktop.tsx b/src/index-desktop.tsx new file mode 100644 index 0000000..12539e1 --- /dev/null +++ b/src/index-desktop.tsx @@ -0,0 +1,30 @@ +import 'ant-design-icons/dist/anticons.min.css' +import React from 'react' +import styled from 'styled-components' +import { TransactionListenerContainer } from './containers/listener' +import { OrderContainer } from './containers/order' +import { WalletContainer } from './containers/wallet' +import './index.css' +import Routers from './routes' +import './utils/i18n' + +const AppDiv = styled.div` + width: 100%; + height: 100%; + background-color: #fff; +` +const DesktopApp: React.FC = () => { + return ( + + + + + + + + + + ) +} + +export default DesktopApp diff --git a/src/index-mobile.tsx b/src/index-mobile.tsx new file mode 100644 index 0000000..3b3a068 --- /dev/null +++ b/src/index-mobile.tsx @@ -0,0 +1,7 @@ +import React from 'react' + +const MobileApp: React.FC = () => { + return

TODO

+} + +export default MobileApp diff --git a/src/index.tsx b/src/index.tsx index 0d0d476..e842c4b 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,29 +1,16 @@ -import 'ant-design-icons/dist/anticons.min.css' import React from 'react' import ReactDOM from 'react-dom' -import styled from 'styled-components' -import { TransactionListenerContainer } from './containers/listener' -import { OrderContainer } from './containers/order' -import { WalletContainer } from './containers/wallet' -import './index.css' -import Routers from './routes' -import './utils/i18n' +import { RippleSpinner } from './components/RippleSpinner' +import { checkIsMobileAndTablet } from './utils/user-agent' -const AppDiv = styled.div` - width: 100%; - height: 100%; - background-color: #fff; -` +const Root = () => { + const App = React.lazy(() => (checkIsMobileAndTablet() ? import('./index-mobile') : import('./index-desktop'))) -ReactDOM.render( - - - - - - - - - , - document.getElementById('root'), -) + return ( + }> + + + ) +} + +ReactDOM.render(, document.getElementById('root')) diff --git a/src/utils/user-agent.ts b/src/utils/user-agent.ts new file mode 100644 index 0000000..e2ffdb2 --- /dev/null +++ b/src/utils/user-agent.ts @@ -0,0 +1,16 @@ +// @ts-nocheck +/* eslint-disable */ +export const checkIsMobileAndTablet = (): boolean => { + const userAgent = navigator.userAgent || navigator.vendor || window.opera + + return ( + /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test( + userAgent, + ) || + /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test( + userAgent.substr(0, 4), + ) + ) +} + +/* eslint-enable */ From a9856425eff4c67846153d2f17f0633a66fef3a0 Mon Sep 17 00:00:00 2001 From: homu-chain Date: Fri, 11 Dec 2020 21:50:01 +0800 Subject: [PATCH 2/5] feat: first supported mobile --- package.json | 1 + public/index.html | 9 +- src/components/Header/styled.tsx | 1 - src/index-mobile.tsx | 22 +++- src/mobile/components/Header/AppHeader.tsx | 115 ++++++++++++++++++ .../components/Header/NavigationMenu.tsx | 51 ++++++++ src/mobile/components/Header/index.ts | 2 + src/mobile/index.css | 6 + src/mobile/route/index.tsx | 48 ++++++++ src/mobile/styled.d.ts | 7 ++ src/mobile/theme.ts | 5 + yarn.lock | 5 + 12 files changed, 262 insertions(+), 10 deletions(-) create mode 100644 src/mobile/components/Header/AppHeader.tsx create mode 100644 src/mobile/components/Header/NavigationMenu.tsx create mode 100644 src/mobile/components/Header/index.ts create mode 100644 src/mobile/index.css create mode 100644 src/mobile/route/index.tsx create mode 100644 src/mobile/styled.d.ts create mode 100644 src/mobile/theme.ts diff --git a/package.json b/package.json index dc0d4ee..acc7fda 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "react-scripts": "3.4.3", "react-test-renderer": "16.13.1", "react-transition-group": "^4.4.1", + "sanitize.css": "^12.0.1", "styled-components": "5.2.0", "unstated-next": "1.1.0", "web3": "1.2.6", diff --git a/public/index.html b/public/index.html index f731b31..2b741b6 100644 --- a/public/index.html +++ b/public/index.html @@ -3,7 +3,7 @@ - + - diff --git a/src/components/Header/styled.tsx b/src/components/Header/styled.tsx index 8f80662..c2d0f9d 100644 --- a/src/components/Header/styled.tsx +++ b/src/components/Header/styled.tsx @@ -60,7 +60,6 @@ export const HeaderPanel = styled.div` export const HeaderLogoBox = styled.h1` margin: 0 0 0 10px; - font-family: Lato; font-size: 18px; font-weight: 800; font-stretch: normal; diff --git a/src/index-mobile.tsx b/src/index-mobile.tsx index 3b3a068..1c303bb 100644 --- a/src/index-mobile.tsx +++ b/src/index-mobile.tsx @@ -1,7 +1,27 @@ +import 'ant-design-icons/dist/anticons.min.css' +import 'mobile/index.css' +import Routers from 'mobile/route' +import { theme } from 'mobile/theme' import React from 'react' +import 'sanitize.css' +import { ThemeProvider } from 'styled-components' +import { TransactionListenerContainer } from './containers/listener' +import { OrderContainer } from './containers/order' +import { WalletContainer } from './containers/wallet' +import './utils/i18n' const MobileApp: React.FC = () => { - return

TODO

+ return ( + + + + + + + + + + ) } export default MobileApp diff --git a/src/mobile/components/Header/AppHeader.tsx b/src/mobile/components/Header/AppHeader.tsx new file mode 100644 index 0000000..b96327a --- /dev/null +++ b/src/mobile/components/Header/AppHeader.tsx @@ -0,0 +1,115 @@ +import { MenuOutlined } from '@ant-design/icons' +import { Modal } from 'antd' +import MetaMaskLogo from 'assets/img/wallet/metamask.png' +import { getChainData, getProviderOptions } from 'components/Header/chain' +import WalletContainer from 'containers/wallet' +import React, { useCallback, useEffect, useMemo } from 'react' +import { Link, useHistory } from 'react-router-dom' +import styled from 'styled-components' +import { ellipsisCenter } from 'utils/common' +import i18n from 'utils/i18n' +import Web3Modal from 'web3modal' + +const AppHeaderWrapper = styled.header` + padding: 0 8px; + height: 60px; + width: 100vw; + display: flex; + align-items: center; + justify-content: space-between; + background: ${props => props.theme.primaryColor}; + + .logo a { + font-size: 18px; + font-style: normal; + font-weight: 800; + line-height: 22px; + letter-spacing: 0em; + text-align: left; + color: #ffffff; + } +` + +const ConnectionButton = styled.div` + background-color: #ffffff; + color: ${props => props.theme.primaryColor}; + box-shadow: 3px 3px 6px rgba(0, 0, 0, 0.08); + border-radius: 10px; + height: 32px; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 4px; + + & > * { + margin: 4px; + } + + img { + width: 20px; + height: 20px; + } +` + +const CLOSE_BY_THE_USER_ERROR_MSG = 'Modal closed by user' +const UNKNOWN_CONNECT_WALLET_FAILED = 'Connect wallet failed, please check wallet settings.' + +export const AppHeader = () => { + const { connectWallet, resetWallet, ckbWallet, connectStatus, web3ModalRef } = WalletContainer.useContainer() + const history = useHistory() + + const handleWalletConnect = useCallback(() => { + connectWallet().catch(error => { + resetWallet() + if (error === CLOSE_BY_THE_USER_ERROR_MSG) { + return + } + Modal.error({ + title: 'Connection Error', + content: error?.message ?? error ?? UNKNOWN_CONNECT_WALLET_FAILED, + }) + }) + }, [connectWallet, resetWallet]) + + useEffect(() => { + const modal = new Web3Modal({ + network: getChainData(1).network, + cacheProvider: true, + providerOptions: getProviderOptions(), + }) + + web3ModalRef.current = modal + + if (modal.cachedProvider) { + handleWalletConnect() + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + const connectButtonElement = useMemo(() => { + if (connectStatus === 'connected') + return ( + history.push('/assets')}> + + metamask + + {ellipsisCenter(ckbWallet.address, 6, 4)} + + + ) + + if (connectStatus === 'connecting') return {i18n.t('header.connecting')} + + return {i18n.t('header.wallet')} + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [connectStatus]) + + return ( + +
+ GLIASWAP +
+ {connectButtonElement} +
+ ) +} diff --git a/src/mobile/components/Header/NavigationMenu.tsx b/src/mobile/components/Header/NavigationMenu.tsx new file mode 100644 index 0000000..f9b1f22 --- /dev/null +++ b/src/mobile/components/Header/NavigationMenu.tsx @@ -0,0 +1,51 @@ +import { Menu } from 'antd' +import React from 'react' +import { useHistory, useLocation } from 'react-router-dom' +import styled from 'styled-components' +import i18n from 'utils/i18n' + +const NavigatorMenuWrapper = styled.div` + box-shadow: 3px 3px 8px rgba(0, 0, 0, 0.08); + + .ant-menu { + background-color: #5c61da; + color: #ffffff; + text-align: center; + } + .ant-menu-horizontal { + border-bottom: none; + } + + .ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-item:hover, + .ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu:hover, + .ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-item-active, + .ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu-active, + .ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-item-open, + .ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu-open, + .ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-item-selected, + .ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu-selected { + color: #ffffff; + font-weight: 600; + border-bottom: 4px solid #ffffff; + } +` + +export const NavigationMenu = () => { + const { pathname } = useLocation() + const history = useHistory() + + return ( + + history.push(`/${e.key}`)} + > + {i18n.t(`header.Trade`)} + {i18n.t(`header.Pool`)} + {i18n.t(`header.Match`)} + + + ) +} diff --git a/src/mobile/components/Header/index.ts b/src/mobile/components/Header/index.ts new file mode 100644 index 0000000..d83f74a --- /dev/null +++ b/src/mobile/components/Header/index.ts @@ -0,0 +1,2 @@ +export { AppHeader } from './AppHeader' +export { NavigationMenu } from './NavigationMenu' diff --git a/src/mobile/index.css b/src/mobile/index.css new file mode 100644 index 0000000..cc638b7 --- /dev/null +++ b/src/mobile/index.css @@ -0,0 +1,6 @@ +@import '~antd/dist/antd.css'; + +body { + font-family: lato, sans-serif, Montserrat, PingFang SC, -apple-system; + font-size: 14px; +} diff --git a/src/mobile/route/index.tsx b/src/mobile/route/index.tsx new file mode 100644 index 0000000..595c36d --- /dev/null +++ b/src/mobile/route/index.tsx @@ -0,0 +1,48 @@ +import { AssetManager } from 'components/Header/AssetsManager' +import WalletContainer from 'containers/wallet' +import { useNotifyTransaction } from 'hooks/useNotifyTransaction' +import { NavigationMenu } from 'mobile/components/Header' +import { AppHeader } from 'mobile/components/Header/AppHeader' +import Trade from 'pages/Trade' +import React, { useEffect } from 'react' +import { BrowserRouter as Router, Route, Switch, useHistory, useLocation } from 'react-router-dom' + +const Control = () => { + useNotifyTransaction() + + return ( + + + + + + + + ) +} + +const RouterRoot = () => { + const { connectStatus } = WalletContainer.useContainer() + const { pathname } = useLocation() + const history = useHistory() + + useEffect(() => { + if (pathname === '/') history.replace('/trade') + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + return ( + <> + + {connectStatus === 'connected' && } + + ) +} + +export default () => { + return ( + + + + ) +} diff --git a/src/mobile/styled.d.ts b/src/mobile/styled.d.ts new file mode 100644 index 0000000..fda52fa --- /dev/null +++ b/src/mobile/styled.d.ts @@ -0,0 +1,7 @@ +import 'styled-components' + +declare module 'styled-components' { + export interface DefaultTheme { + primaryColor: string + } +} diff --git a/src/mobile/theme.ts b/src/mobile/theme.ts new file mode 100644 index 0000000..45a72c2 --- /dev/null +++ b/src/mobile/theme.ts @@ -0,0 +1,5 @@ +import { DefaultTheme } from 'styled-components' + +export const theme: DefaultTheme = { + primaryColor: '#6b70e0', +} diff --git a/yarn.lock b/yarn.lock index f175c3d..6eb69ac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13184,6 +13184,11 @@ sanitize.css@^10.0.0: resolved "https://registry.yarnpkg.com/sanitize.css/-/sanitize.css-10.0.0.tgz#b5cb2547e96d8629a60947544665243b1dc3657a" integrity sha512-vTxrZz4dX5W86M6oVWVdOVe72ZiPs41Oi7Z6Km4W5Turyz28mrXSJhhEBZoRtzJWIv3833WKVwLSDWWkEfupMg== +sanitize.css@^12.0.1: + version "12.0.1" + resolved "https://registry.yarnpkg.com/sanitize.css/-/sanitize.css-12.0.1.tgz#f20369357557ba2b41d7278eeb3ea691a3bee514" + integrity sha512-QbusSBnWHaRBZeTxsJyknwI0q+q6m1NtLBmB76JfW/rdVN7Ws6Zz70w65+430/ouVcdNVT3qwrDgrM6PaYyRtw== + sass-loader@8.0.2: version "8.0.2" resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-8.0.2.tgz#debecd8c3ce243c76454f2e8290482150380090d" From df46946b7db033f33f7f592f28682b8ea21ff748 Mon Sep 17 00:00:00 2001 From: homu-chain Date: Mon, 14 Dec 2020 10:19:04 +0800 Subject: [PATCH 3/5] feat: add background image --- src/mobile/route/index.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/mobile/route/index.tsx b/src/mobile/route/index.tsx index 595c36d..eff6742 100644 --- a/src/mobile/route/index.tsx +++ b/src/mobile/route/index.tsx @@ -6,6 +6,14 @@ import { AppHeader } from 'mobile/components/Header/AppHeader' import Trade from 'pages/Trade' import React, { useEffect } from 'react' import { BrowserRouter as Router, Route, Switch, useHistory, useLocation } from 'react-router-dom' +import styled from 'styled-components' +import BackgroundImageUrl from '../../assets/img/dex-bg.png' + +const MobileWrapper = styled.div` + position: relative; + background: url('${BackgroundImageUrl}') fixed center; + background-size: cover; +` const Control = () => { useNotifyTransaction() @@ -32,10 +40,10 @@ const RouterRoot = () => { }, []) return ( - <> + {connectStatus === 'connected' && } - + ) } From 7fa80c2b811b496c809b8a228c8791056d54d460 Mon Sep 17 00:00:00 2001 From: homu-chain Date: Mon, 14 Dec 2020 16:42:10 +0800 Subject: [PATCH 4/5] feat: display background --- src/index-desktop.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/index-desktop.tsx b/src/index-desktop.tsx index 12539e1..711f263 100644 --- a/src/index-desktop.tsx +++ b/src/index-desktop.tsx @@ -11,7 +11,6 @@ import './utils/i18n' const AppDiv = styled.div` width: 100%; height: 100%; - background-color: #fff; ` const DesktopApp: React.FC = () => { return ( From edbca28506d201a6fc73aab7572c62bdde17d7e5 Mon Sep 17 00:00:00 2001 From: homu-chain Date: Tue, 15 Dec 2020 22:55:52 +0800 Subject: [PATCH 5/5] feat: impl an AssetManagerWrapper for AssetManager --- src/components/Header/AssetsManager/index.tsx | 14 ++++++++++---- src/mobile/components/AssetManager/index.tsx | 15 +++++++++++++++ src/mobile/route/index.tsx | 4 ++-- 3 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 src/mobile/components/AssetManager/index.tsx diff --git a/src/components/Header/AssetsManager/index.tsx b/src/components/Header/AssetsManager/index.tsx index 98f2265..44aac14 100644 --- a/src/components/Header/AssetsManager/index.tsx +++ b/src/components/Header/AssetsManager/index.tsx @@ -35,7 +35,7 @@ const AssetManagerWrapper = styled.div` overflow-y: auto; ` -export const AssetManager: React.FC = () => { +export const AssetManagerControl = () => { // check and clean the pending cell when the cell was dead useEffect(() => { const taskId = setInterval(() => { @@ -49,12 +49,18 @@ export const AssetManager: React.FC = () => { } }) + return ( + + + + ) +} + +export const AssetManager: React.FC = () => { return ( - - - + ) diff --git a/src/mobile/components/AssetManager/index.tsx b/src/mobile/components/AssetManager/index.tsx new file mode 100644 index 0000000..2b6bcd3 --- /dev/null +++ b/src/mobile/components/AssetManager/index.tsx @@ -0,0 +1,15 @@ +import { AssetManagerControl } from 'components/Header/AssetsManager' +import React from 'react' +import styled from 'styled-components' + +const MobileAssetManagerWrapper = styled.div` + background: #fff; +` + +export const AssetManager = () => { + return ( + + + + ) +} diff --git a/src/mobile/route/index.tsx b/src/mobile/route/index.tsx index eff6742..bad33f4 100644 --- a/src/mobile/route/index.tsx +++ b/src/mobile/route/index.tsx @@ -1,6 +1,6 @@ -import { AssetManager } from 'components/Header/AssetsManager' import WalletContainer from 'containers/wallet' import { useNotifyTransaction } from 'hooks/useNotifyTransaction' +import { AssetManager } from 'mobile/components/AssetManager' import { NavigationMenu } from 'mobile/components/Header' import { AppHeader } from 'mobile/components/Header/AppHeader' import Trade from 'pages/Trade' @@ -20,7 +20,7 @@ const Control = () => { return ( - +