From d88c2a5eff58465bf2df9e6e6caadead88d48aa4 Mon Sep 17 00:00:00 2001 From: Reckless_Satoshi <90936742+Reckless-Satoshi@users.noreply.github.com> Date: Fri, 24 Feb 2023 19:17:13 +0000 Subject: [PATCH] Add App context (#369) * Refactor fetchRobot * Add appcontext * Robot recovery fixes * Add usecontext on maker and settings forms * Add usecontext to booktable * Add useContext to order page and main dialogs * Small fixes --- .github/pull_request_template.md | 7 +- .pre-commit-config.yaml | 20 +- api/views.py | 5 +- frontend/src/App.tsx | 25 +- frontend/src/basic/BookPage/index.tsx | 20 - frontend/src/basic/Main.tsx | 379 ++----------- frontend/src/basic/MainDialogs/index.tsx | 53 +- frontend/src/basic/MakerPage/index.tsx | 49 +- frontend/src/basic/NavBar/MoreTooltip.tsx | 9 +- frontend/src/basic/NavBar/NavBar.tsx | 60 +-- frontend/src/basic/OrderPage/index.tsx | 41 +- frontend/src/basic/RobotPage/Recovery.tsx | 21 +- frontend/src/basic/RobotPage/RobotProfile.tsx | 16 +- frontend/src/basic/RobotPage/TokenInput.tsx | 2 +- frontend/src/basic/RobotPage/Welcome.tsx | 2 +- frontend/src/basic/RobotPage/index.tsx | 114 +--- frontend/src/basic/SettingsPage/index.tsx | 31 +- frontend/src/components/BookTable/index.tsx | 34 +- .../components/Charts/DepthChart/index.tsx | 32 +- .../components/Dialogs/CoordinatorSummary.tsx | 2 +- .../src/components/MakerForm/MakerForm.tsx | 27 +- .../src/components/SettingsForm/index.tsx | 18 +- frontend/src/components/TorConnection.tsx | 10 +- frontend/src/contexts/AppContext.tsx | 501 ++++++++++++++++++ frontend/src/models/Robot.model.ts | 1 + frontend/src/pro/Main.tsx | 212 ++------ frontend/src/pro/Widgets/Book.tsx | 19 +- frontend/src/pro/Widgets/Depth.tsx | 22 +- frontend/src/pro/Widgets/Maker.tsx | 39 +- frontend/src/pro/Widgets/Settings.tsx | 25 +- frontend/static/locales/ca.json | 3 +- frontend/static/locales/cs.json | 3 +- frontend/static/locales/de.json | 3 +- frontend/static/locales/en.json | 3 +- frontend/static/locales/es.json | 3 +- frontend/static/locales/eu.json | 3 +- frontend/static/locales/fr.json | 3 +- frontend/static/locales/it.json | 3 +- frontend/static/locales/pl.json | 3 +- frontend/static/locales/pt.json | 3 +- frontend/static/locales/ru.json | 3 +- frontend/static/locales/sv.json | 3 +- frontend/static/locales/th.json | 3 +- frontend/static/locales/zh-SI.json | 3 +- frontend/static/locales/zh-TR.json | 3 +- 45 files changed, 825 insertions(+), 1016 deletions(-) create mode 100644 frontend/src/contexts/AppContext.tsx diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index a85f991a..e60f4c47 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,5 +1,8 @@ ## What does this PR do? -Fixes # +Fixes # + +This PR introduces/refactors/... ## Checklist before merging -- [ ] Make sure you have installed and initialized [pre-commit](https://pre-commit.com). `pip install pre-commit` and `pre-commit install` +- [ ] If it's a frontend feature, I have ran prettier `cd frontend; npm run format`. If it's a mobile app feature I ran `cd mobile; npm run format`. +- [ ] If I added new phrases to the user interface, I have ran prettier `cd frontend/static/locales; python collect_phrases.py` to collect them for translation. \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2181decf..b90de78d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -21,17 +21,15 @@ repos: - id: check-docstring-first - repo: local hooks: - - id: collect-phrases - name: collect-phrases - stages: - - commit - - merge-commit - language: system - files: ^frontend/src/ - types_or: [javascript, jsx, ts, tsx] # uses https://github.com/pre-commit/identify - entry: bash -c 'cd frontend/static/locales && python3 collect_phrases.py' - - repo: local - hooks: + # - id: collect-phrases + # name: Collect i18n phrases + # stages: + # - commit + # - merge-commit + # language: system + # files: ^frontend/ + # types_or: [javascript, jsx, ts, tsx] # uses https://github.com/pre-commit/identify + # entry: bash -c 'cd frontend/static/locales && python3 collect_phrases.py' - id: prettier-frontend name: prettier-frontend stages: diff --git a/api/views.py b/api/views.py index 7780db5b..eb4dcc9b 100644 --- a/api/views.py +++ b/api/views.py @@ -759,9 +759,8 @@ class UserView(APIView): if last_order: context["last_order_id"] = last_order.id - # Sends the welcome back message, only if created +3 mins ago - if request.user.date_joined < (timezone.now() - timedelta(minutes=3)): - context["found"] = "We found your Robot avatar. Welcome back!" + # Sends the welcome back message. + context["found"] = "We found your Robot avatar. Welcome back!" return Response(context, status=status.HTTP_202_ACCEPTED) else: # It is unlikely, but maybe the nickname is taken (1 in 20 Billion chance) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 21ca5d04..8ef23fd3 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -2,6 +2,7 @@ import React, { Suspense, useState, useEffect } from 'react'; import ReactDOM from 'react-dom/client'; import Main from './basic/Main'; import { CssBaseline } from '@mui/material'; +import { AppContextProvider } from './contexts/AppContext'; import { ThemeProvider, createTheme, Theme } from '@mui/material/styles'; import UnsafeAlert from './components/UnsafeAlert'; import TorConnectionBadge from './components/TorConnection'; @@ -29,14 +30,6 @@ const makeTheme = function (settings: Settings) { const App = (): JSX.Element => { const [theme, setTheme] = useState(makeTheme(new Settings())); const [settings, setSettings] = useState(new Settings()); - const [torStatus, setTorStatus] = useState('NOTINIT'); - - useEffect(() => { - window.addEventListener('torStatus', (event) => { - // UX improv: delay the "Conencted" status by 10 secs to avoid long waits for first requests - setTimeout(() => setTorStatus(event?.detail), event?.detail === '"Done"' ? 10000 : 0); - }); - }, []); useEffect(() => { setTheme(makeTheme(settings)); @@ -50,13 +43,15 @@ const App = (): JSX.Element => { - - {window.NativeRobosats === undefined ? ( - - ) : ( - - )} -
+ + + {window.NativeRobosats === undefined ? ( + + ) : ( + + )} +
+ diff --git a/frontend/src/basic/BookPage/index.tsx b/frontend/src/basic/BookPage/index.tsx index 99136fa0..4a450a62 100644 --- a/frontend/src/basic/BookPage/index.tsx +++ b/frontend/src/basic/BookPage/index.tsx @@ -147,56 +147,36 @@ const BookPage = ({ > fetchBook()} - book={book} - fav={fav} - setFav={setFav} maxWidth={maxBookTableWidth} // EM units maxHeight={windowSize.height * 0.825 - 5} // EM units fullWidth={windowSize.width} // EM units fullHeight={windowSize.height} // EM units defaultFullscreen={false} onOrderClicked={onOrderClicked} - baseUrl={baseUrl} /> ) : view === 'depth' ? ( ) : ( fetchBook()} - fav={fav} - setFav={setFav} maxWidth={windowSize.width * 0.97} // EM units maxHeight={windowSize.height * 0.825 - 5} // EM units fullWidth={windowSize.width} // EM units fullHeight={windowSize.height} // EM units defaultFullscreen={false} onOrderClicked={onOrderClicked} - baseUrl={baseUrl} /> )} diff --git a/frontend/src/basic/Main.tsx b/frontend/src/basic/Main.tsx index 6cbea922..a1ceaf69 100644 --- a/frontend/src/basic/Main.tsx +++ b/frontend/src/basic/Main.tsx @@ -1,312 +1,63 @@ -import React, { useEffect, useState } from 'react'; +import React, { useContext } from 'react'; import { HashRouter, BrowserRouter, Switch, Route } from 'react-router-dom'; -import { useTheme, Box, Slide, Typography } from '@mui/material'; +import { Box, Slide, Typography } from '@mui/material'; import RobotPage from './RobotPage'; import MakerPage from './MakerPage'; import BookPage from './BookPage'; import OrderPage from './OrderPage'; import SettingsPage from './SettingsPage'; -import NavBar, { Page } from './NavBar'; -import MainDialogs, { OpenDialogs } from './MainDialogs'; +import NavBar from './NavBar'; +import MainDialogs from './MainDialogs'; import RobotAvatar from '../components/RobotAvatar'; -import { - Book, - LimitList, - Maker, - Robot, - Info, - Settings, - Favorites, - defaultMaker, - defaultInfo, - Coordinator, - Order, -} from '../models'; -import { apiClient } from '../services/api'; -import { checkVer, getHost } from '../utils'; -import { sha256 } from 'js-sha256'; - -import defaultCoordinators from '../../static/federation.json'; import { useTranslation } from 'react-i18next'; import Notifications from '../components/Notifications'; +import { AppContextProps, AppContext } from '../contexts/AppContext'; -const getWindowSize = function (fontSize: number) { - // returns window size in EM units - return { - width: window.innerWidth / fontSize, - height: window.innerHeight / fontSize, - }; -}; - -// Refresh delays (ms) according to Order status -const statusToDelay = [ - 3000, // 'Waiting for maker bond' - 35000, // 'Public' - 180000, // 'Paused' - 3000, // 'Waiting for taker bond' - 999999, // 'Cancelled' - 999999, // 'Expired' - 8000, // 'Waiting for trade collateral and buyer invoice' - 8000, // 'Waiting only for seller trade collateral' - 8000, // 'Waiting only for buyer invoice' - 10000, // 'Sending fiat - In chatroom' - 10000, // 'Fiat sent - In chatroom' - 100000, // 'In dispute' - 999999, // 'Collaboratively cancelled' - 10000, // 'Sending satoshis to buyer' - 999999, // 'Sucessful trade' - 30000, // 'Failed lightning network routing' - 300000, // 'Wait for dispute resolution' - 300000, // 'Maker lost dispute' - 300000, // 'Taker lost dispute' -]; - -interface SlideDirection { - in: 'left' | 'right' | undefined; - out: 'left' | 'right' | undefined; -} - -interface MainProps { - settings: Settings; - torStatus: 'NOTINIT' | 'STARTING' | '"Done"' | 'DONE'; - setSettings: (state: Settings) => void; -} - -const Main = ({ torStatus, settings, setSettings }: MainProps): JSX.Element => { +const Main = (): JSX.Element => { const { t } = useTranslation(); - const theme = useTheme(); - - // All app data structured - const [book, setBook] = useState({ orders: [], loading: true }); - const [limits, setLimits] = useState<{ list: LimitList; loading: boolean }>({ - list: [], - loading: true, - }); - const [robot, setRobot] = useState(new Robot()); - const [maker, setMaker] = useState(defaultMaker); - const [info, setInfo] = useState(defaultInfo); - const [coordinators, setCoordinators] = useState(defaultCoordinators); - const [baseUrl, setBaseUrl] = useState(''); - const [fav, setFav] = useState({ type: null, mode: 'fiat', currency: 0 }); - - const [delay, setDelay] = useState(60000); - const [timer, setTimer] = useState(setInterval(() => null, delay)); - const [order, setOrder] = useState(undefined); - const [badOrder, setBadOrder] = useState(undefined); + const { + book, + fetchBook, + maker, + setMaker, + clearOrder, + torStatus, + settings, + limits, + fetchLimits, + robot, + setRobot, + fetchRobot, + setOrder, + setDelay, + info, + fav, + setFav, + baseUrl, + order, + page, + setPage, + slideDirection, + setSlideDirection, + currentOrder, + setCurrentOrder, + closeAll, + open, + setOpen, + windowSize, + badOrder, + navbarHeight, + setBadOrder, + } = useContext(AppContext); const Router = window.NativeRobosats === undefined ? BrowserRouter : HashRouter; const basename = window.NativeRobosats === undefined ? '' : window.location.pathname; - const entryPage: Page | '' = - window.NativeRobosats === undefined ? window.location.pathname.split('/')[1] : ''; - const [page, setPage] = useState(entryPage == '' ? 'robot' : entryPage); - const [slideDirection, setSlideDirection] = useState({ - in: undefined, - out: undefined, - }); - - const [currentOrder, setCurrentOrder] = useState(undefined); - - const navbarHeight = 2.5; - const closeAll = { - more: false, - learn: false, - community: false, - info: false, - coordinator: false, - stats: false, - update: false, - profile: false, - }; - const [open, setOpen] = useState(closeAll); - - const [windowSize, setWindowSize] = useState<{ width: number; height: number }>( - getWindowSize(theme.typography.fontSize), - ); - - useEffect(() => { - if (typeof window !== undefined) { - window.addEventListener('resize', onResize); - } - - if (baseUrl != '') { - fetchBook(); - fetchLimits(); - } - return () => { - if (typeof window !== undefined) { - window.removeEventListener('resize', onResize); - } - }; - }, [baseUrl]); - - useEffect(() => { - let host = ''; - if (window.NativeRobosats === undefined) { - host = getHost(); - } else { - host = - settings.network === 'mainnet' - ? coordinators[0].mainnetOnion - : coordinators[0].testnetOnion; - } - setBaseUrl(`${location.protocol}//${host}`); - }, [settings.network]); - - useEffect(() => { - setWindowSize(getWindowSize(theme.typography.fontSize)); - }, [theme.typography.fontSize]); - - const onResize = function () { - setWindowSize(getWindowSize(theme.typography.fontSize)); - }; - - const fetchBook = function () { - setBook({ ...book, loading: true }); - apiClient.get(baseUrl, '/api/book/').then((data: any) => - setBook({ - loading: false, - orders: data.not_found ? [] : data, - }), - ); - }; - - const fetchLimits = async () => { - setLimits({ ...limits, loading: true }); - const data = apiClient.get(baseUrl, '/api/limits/').then((data) => { - setLimits({ list: data ?? [], loading: false }); - return data; - }); - return await data; - }; - - const fetchInfo = function () { - setInfo({ ...info, loading: true }); - apiClient.get(baseUrl, '/api/info/').then((data: Info) => { - const versionInfo: any = checkVer(data.version.major, data.version.minor, data.version.patch); - setInfo({ - ...data, - openUpdateClient: versionInfo.updateAvailable, - coordinatorVersion: versionInfo.coordinatorVersion, - clientVersion: versionInfo.clientVersion, - loading: false, - }); - }); - }; - - useEffect(() => { - if (open.stats || open.coordinator || info.coordinatorVersion == 'v?.?.?') { - fetchInfo(); - } - }, [open.stats, open.coordinator]); - - useEffect(() => { - // Sets Setting network from coordinator API param if accessing via web - if (settings.network == undefined && info.network) { - setSettings((settings: Settings) => { - return { ...settings, network: info.network }; - }); - } - }, [info]); - - const fetchRobot = function ({ keys = false }) { - const requestBody = { - token_sha256: sha256(robot.token), - }; - if (keys) { - requestBody.pub_key = robot.pubKey; - requestBody.enc_priv_key = robot.encPrivKey; - } - - setRobot({ ...robot, loading: true }); - apiClient.post(baseUrl, '/api/user/', requestBody).then((data: any) => { - setCurrentOrder( - data.active_order_id - ? data.active_order_id - : data.last_order_id - ? data.last_order_id - : null, - ); - setRobot({ - ...robot, - nickname: data.nickname, - token: robot.token, - loading: false, - avatarLoaded: robot.nickname === data.nickname, - activeOrderId: data.active_order_id ? data.active_order_id : null, - lastOrderId: data.last_order_id ? data.last_order_id : null, - referralCode: data.referral_code, - earnedRewards: data.earned_rewards ?? 0, - stealthInvoices: data.wants_stealth, - tgEnabled: data.tg_enabled, - tgBotName: data.tg_bot_name, - tgToken: data.tg_token, - bitsEntropy: data.token_bits_entropy, - shannonEntropy: data.token_shannon_entropy, - pubKey: data.public_key, - encPrivKey: data.encrypted_private_key, - copiedToken: data.found ? true : robot.copiedToken, - }); - }); - }; - - useEffect(() => { - if (baseUrl != '' && page != 'robot') { - if (open.profile || (robot.token && robot.nickname === null)) { - fetchRobot({ keys: false }); // fetch existing robot - } else if (robot.token && robot.encPrivKey && robot.pubKey) { - fetchRobot({ keys: true }); // create new robot with existing token and keys (on network and coordinator change) - } - } - }, [open.profile, baseUrl]); - - // Fetch current order at load and in a loop - useEffect(() => { - if (currentOrder != undefined && (page == 'order' || (order == badOrder) == undefined)) { - fetchOrder(); - } - }, [currentOrder, page]); - - useEffect(() => { - clearInterval(timer); - setTimer(setInterval(fetchOrder, delay)); - return () => clearInterval(timer); - }, [delay, currentOrder, page, badOrder]); - - const orderReceived = function (data: any) { - if (data.bad_request != undefined) { - setBadOrder(data.bad_request); - setDelay(99999999); - setOrder(undefined); - } else { - setDelay( - data.status >= 0 && data.status <= 18 - ? page == 'order' - ? statusToDelay[data.status] - : statusToDelay[data.status] * 5 - : 99999999, - ); - setOrder(data); - setBadOrder(undefined); - } - }; - - const fetchOrder = function () { - if (currentOrder != undefined) { - apiClient.get(baseUrl, '/api/order/?order_id=' + currentOrder).then(orderReceived); - } - }; - - const clearOrder = function () { - setOrder(undefined); - setBadOrder(undefined); - }; return ( - {/* load robot avatar image, set avatarLoaded: true */} { { appear={slideDirection.in != undefined} >
- +
@@ -432,17 +170,8 @@ const Main = ({ torStatus, settings, setSettings }: MainProps): JSX.Element => { >
@@ -456,34 +185,14 @@ const Main = ({ torStatus, settings, setSettings }: MainProps): JSX.Element => { appear={slideDirection.in != undefined} >
- +
- +
void; - info: Info; - robot: Robot; - setRobot: (state: Robot) => void; - setPage: (state: Page) => void; - setCurrentOrder: (state: number) => void; - closeAll: OpenDialogs; - baseUrl: string; -} +const MainDialogs = (): JSX.Element => { + const { + open, + setOpen, + info, + limits, + closeAll, + robot, + setRobot, + setPage, + setCurrentOrder, + baseUrl, + } = useContext(AppContext); + + const [maxAmount, setMaxAmount] = useState('...loading...'); + + useEffect(() => { + if (limits.list[1000]) { + setMaxAmount(pn(limits.list[1000].max_amount * 100000000)); + } + }, [limits.list]); -const MainDialogs = ({ - open, - setOpen, - info, - closeAll, - robot, - setRobot, - setPage, - setCurrentOrder, - baseUrl, -}: MainDialogsProps): JSX.Element => { useEffect(() => { if (info.openUpdateClient) { setOpen({ ...closeAll, update: true }); @@ -61,7 +60,7 @@ const MainDialogs = ({ /> setOpen({ ...open, info: false })} /> setOpen({ ...open, learn: false })} /> diff --git a/frontend/src/basic/MakerPage/index.tsx b/frontend/src/basic/MakerPage/index.tsx index 0a3dd901..3a231a93 100644 --- a/frontend/src/basic/MakerPage/index.tsx +++ b/frontend/src/basic/MakerPage/index.tsx @@ -1,52 +1,26 @@ -import React, { useState } from 'react'; +import React, { useContext, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useHistory } from 'react-router-dom'; import { Grid, Paper, Collapse, Typography } from '@mui/material'; -import { LimitList, Maker, Book, Favorites, Order } from '../../models'; - import { filterOrders } from '../../utils'; import MakerForm from '../../components/MakerForm'; import BookTable from '../../components/BookTable'; -import { Page } from '../NavBar'; +import { AppContext, AppContextProps } from '../../contexts/AppContext'; interface MakerPageProps { - limits: { list: LimitList; loading: boolean }; - fetchLimits: () => void; - book: Book; - fav: Favorites; - maker: Maker; - setFav: (state: Favorites) => void; - setMaker: (state: Maker) => void; - clearOrder: () => void; - windowSize: { width: number; height: number }; hasRobot: boolean; - setCurrentOrder: (state: number) => void; - setPage: (state: Page) => void; - baseUrl: string; } -const MakerPage = ({ - limits, - fetchLimits, - book, - fav, - maker, - setFav, - setMaker, - clearOrder, - windowSize, - setCurrentOrder, - setPage, - hasRobot = false, - baseUrl, -}: MakerPageProps): JSX.Element => { +const MakerPage = ({ hasRobot = false }: MakerPageProps): JSX.Element => { + const { book, fav, maker, clearOrder, windowSize, setCurrentOrder, navbarHeight, setPage } = + useContext(AppContext); const { t } = useTranslation(); const history = useHistory(); - const maxHeight = windowSize.height * 0.85 - 3; + const maxHeight = (windowSize.height - navbarHeight) * 0.85 - 3; const [showMatches, setShowMatches] = useState(false); const matches = filterOrders({ @@ -71,14 +45,13 @@ const MakerPage = ({ @@ -95,12 +68,6 @@ const MakerPage = ({ }} > { clearOrder(); setCurrentOrder(id); @@ -113,8 +80,6 @@ const MakerPage = ({ onSubmit={() => setShowMatches(matches.length > 0)} onReset={() => setShowMatches(false)} submitButtonLabel={matches.length > 0 && !showMatches ? 'Submit' : 'Create order'} - setPage={setPage} - baseUrl={baseUrl} /> diff --git a/frontend/src/basic/NavBar/MoreTooltip.tsx b/frontend/src/basic/NavBar/MoreTooltip.tsx index 8a3f3dcd..276addd0 100644 --- a/frontend/src/basic/NavBar/MoreTooltip.tsx +++ b/frontend/src/basic/NavBar/MoreTooltip.tsx @@ -21,19 +21,12 @@ const StyledTooltip = styled(({ className, ...props }: TooltipProps) => ( interface MoreTooltipProps { open: OpenDialogs; - nickname: string | null; setOpen: (state: OpenDialogs) => void; closeAll: OpenDialogs; children: JSX.Element; } -const MoreTooltip = ({ - open, - setOpen, - closeAll, - nickname, - children, -}: MoreTooltipProps): JSX.Element => { +const MoreTooltip = ({ open, setOpen, closeAll, children }: MoreTooltipProps): JSX.Element => { const { t } = useTranslation(); const theme = useTheme(); return ( diff --git a/frontend/src/basic/NavBar/NavBar.tsx b/frontend/src/basic/NavBar/NavBar.tsx index 7541874a..0fc9236a 100644 --- a/frontend/src/basic/NavBar/NavBar.tsx +++ b/frontend/src/basic/NavBar/NavBar.tsx @@ -1,11 +1,9 @@ -import React, { useEffect } from 'react'; +import React, { useContext, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { useHistory } from 'react-router-dom'; import { Tabs, Tab, Paper, useTheme } from '@mui/material'; import MoreTooltip from './MoreTooltip'; -import { OpenDialogs } from '../MainDialogs'; - import { Page } from '.'; import { @@ -17,47 +15,35 @@ import { MoreHoriz, } from '@mui/icons-material'; import RobotAvatar from '../../components/RobotAvatar'; - -type Direction = 'left' | 'right' | undefined; +import { AppContext, AppContextProps } from '../../contexts/AppContext'; interface NavBarProps { - page: Page; - nickname?: string | null; - setPage: (state: Page) => void; - setSlideDirection: (state: { in: Direction; out: Direction }) => void; width: number; height: number; - open: OpenDialogs; - setOpen: (state: OpenDialogs) => void; - closeAll: OpenDialogs; - currentOrder: number | undefined; hasRobot: boolean; - baseUrl: string; - color: 'primary' | 'secondary'; } -const NavBar = ({ - page, - setPage, - setSlideDirection, - open, - nickname = null, - setOpen, - closeAll, - width, - height, - currentOrder, - hasRobot = false, - baseUrl, - color, -}: NavBarProps): JSX.Element => { +const NavBar = ({ width, height, hasRobot = false }: NavBarProps): JSX.Element => { + const { + page, + settings, + setPage, + setSlideDirection, + open, + robot, + setOpen, + closeAll, + currentOrder, + baseUrl, + } = useContext(AppContext); + const theme = useTheme(); const { t } = useTranslation(); const history = useHistory(); const smallBar = width < 50; const tabSx = smallBar - ? { position: 'relative', bottom: nickname ? '1em' : '0em', minWidth: '1em' } + ? { position: 'relative', bottom: robot.nickname ? '1em' : '0em', minWidth: '1em' } : { position: 'relative', bottom: '1em', minWidth: '2em' }; const pagesPosition = { robot: 1, @@ -102,21 +88,21 @@ const NavBar = ({ TabIndicatorProps={{ sx: { height: '0.3em', position: 'absolute', top: 0 } }} variant='fullWidth' value={page} - indicatorColor={color} - textColor={color} + indicatorColor={settings.network === 'mainnet' ? 'primary' : 'secondary'} + textColor={settings.network === 'mainnet' ? 'primary' : 'secondary'} onChange={changePage} > setOpen({ ...closeAll, profile: !open.profile })} icon={ - nickname ? ( + robot.nickname && robot.avatarLoaded ? ( ) : ( @@ -171,7 +157,7 @@ const NavBar = ({ open.more ? null : setOpen({ ...open, more: true }); }} icon={ - + } diff --git a/frontend/src/basic/OrderPage/index.tsx b/frontend/src/basic/OrderPage/index.tsx index 5f0a0c2d..c0aa632a 100644 --- a/frontend/src/basic/OrderPage/index.tsx +++ b/frontend/src/basic/OrderPage/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Tab, Tabs, Paper, CircularProgress, Grid, Typography, Box } from '@mui/material'; import { useHistory } from 'react-router-dom'; @@ -9,40 +9,31 @@ import OrderDetails from '../../components/OrderDetails'; import { Page } from '../NavBar'; import { Order, Settings } from '../../models'; import { apiClient } from '../../services/api'; +import { AppContext, AppContextProps } from '../../contexts/AppContext'; interface OrderPageProps { - windowSize: { width: number; height: number }; - order: Order; - settings: Settings; - setOrder: (state: Order) => void; - setCurrentOrder: (state: number) => void; - fetchOrder: () => void; - badOrder: string | undefined; - setBadOrder: (state: string | undefined) => void; hasRobot: boolean; - setPage: (state: Page) => void; - baseUrl: string; locationOrderId: number; } -const OrderPage = ({ - windowSize, - order, - settings, - setOrder, - setCurrentOrder, - badOrder, - setBadOrder, - setPage, - hasRobot = false, - baseUrl, - locationOrderId, -}: OrderPageProps): JSX.Element => { +const OrderPage = ({ hasRobot = false, locationOrderId }: OrderPageProps): JSX.Element => { + const { + windowSize, + order, + settings, + setOrder, + setCurrentOrder, + badOrder, + setBadOrder, + setPage, + baseUrl, + navbarHeight, + } = useContext(AppContext); const { t } = useTranslation(); const history = useHistory(); const doublePageWidth: number = 50; - const maxHeight: number = windowSize.height * 0.85 - 3; + const maxHeight: number = (windowSize.height - navbarHeight) * 0.85 - 3; const [tab, setTab] = useState<'order' | 'contract'>('contract'); diff --git a/frontend/src/basic/RobotPage/Recovery.tsx b/frontend/src/basic/RobotPage/Recovery.tsx index c4560dd4..ee8fd914 100644 --- a/frontend/src/basic/RobotPage/Recovery.tsx +++ b/frontend/src/basic/RobotPage/Recovery.tsx @@ -1,12 +1,7 @@ import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { Button, Collapse, Grid, Typography, useTheme } from '@mui/material'; -import { useParams } from 'react-router-dom'; - -import { Page } from '../NavBar'; +import { Button, Grid, Typography, useTheme } from '@mui/material'; import { Robot } from '../../models'; -import { Casino, Download, ContentCopy, SmartToy, Bolt } from '@mui/icons-material'; -import RobotAvatar from '../../components/RobotAvatar'; import TokenInput from './TokenInput'; import Key from '@mui/icons-material/Key'; @@ -17,8 +12,6 @@ interface RecoveryProps { inputToken: string; setInputToken: (state: string) => void; getGenerateRobot: (token: string) => void; - setPage: (state: Page) => void; - baseUrl: string; } const Recovery = ({ @@ -28,11 +21,8 @@ const Recovery = ({ setView, setInputToken, getGenerateRobot, - setPage, - baseUrl, }: RecoveryProps): JSX.Element => { const { t } = useTranslation(); - const theme = useTheme(); const recoveryDisabled = () => { return !(inputToken.length > 20); @@ -47,11 +37,14 @@ const Recovery = ({ return ( + + + {t('Robot recovery')} + + - {t( - 'Please, introduce your robot token to re-build your robot and gain access to its trades.', - )} + {t('Enter your robot token to re-build your robot and gain access to its trades.')} diff --git a/frontend/src/basic/RobotPage/RobotProfile.tsx b/frontend/src/basic/RobotPage/RobotProfile.tsx index 38d984ef..60a6c8f4 100644 --- a/frontend/src/basic/RobotPage/RobotProfile.tsx +++ b/frontend/src/basic/RobotPage/RobotProfile.tsx @@ -7,7 +7,6 @@ import RobotAvatar from '../../components/RobotAvatar'; import TokenInput from './TokenInput'; import { Page } from '../NavBar'; import { Robot } from '../../models'; -import { genBase62Token } from '../../utils'; interface RobotProfileProps { robot: Robot; @@ -21,7 +20,6 @@ interface RobotProfileProps { setPage: (state: Page) => void; baseUrl: string; badRequest: string; - robotFound: boolean; width: number; } @@ -37,7 +35,6 @@ const RobotProfile = ({ setView, badRequest, baseUrl, - robotFound, width, }: RobotProfileProps): JSX.Element => { const { t } = useTranslation(); @@ -104,15 +101,13 @@ const RobotProfile = ({ /> - {/* {robotFound ? ( - - - {t('Welcome back!')} - - + {robot.found ? ( + + {t('Welcome back!')} + ) : ( <> - )} */} + )} {robot.activeOrderId ? ( @@ -184,7 +179,6 @@ const RobotProfile = ({