From bbdd53d2aa5be415e5c381ecf19a6446dbc05759 Mon Sep 17 00:00:00 2001 From: Mark Sinclair Date: Fri, 22 Apr 2022 11:30:15 +0100 Subject: [PATCH] Add terminal in dev mode --- nym-wallet/src/components/AppBar.tsx | 12 +- nym-wallet/src/context/main.tsx | 20 ++- nym-wallet/src/index.tsx | 2 + nym-wallet/src/pages/terminal/index.tsx | 167 ++++++++++++++++++++++++ 4 files changed, 199 insertions(+), 2 deletions(-) create mode 100644 nym-wallet/src/pages/terminal/index.tsx diff --git a/nym-wallet/src/components/AppBar.tsx b/nym-wallet/src/components/AppBar.tsx index b5ee0ab55d..4dbefa1c25 100644 --- a/nym-wallet/src/components/AppBar.tsx +++ b/nym-wallet/src/components/AppBar.tsx @@ -1,12 +1,15 @@ import React, { useContext } from 'react'; import { AppBar as MuiAppBar, Grid, IconButton, Toolbar } from '@mui/material'; import { Logout } from '@mui/icons-material'; +import TerminalIcon from '@mui/icons-material/Terminal'; import { ClientContext } from '../context/main'; import { NetworkSelector } from './NetworkSelector'; import { Node as NodeIcon } from '../svg-icons/node'; +import { config } from '../../config'; export const AppBar = () => { - const { showSettings, logOut, handleShowSettings } = useContext(ClientContext); + const { showSettings, logOut, handleShowSettings, handleShowTerminal } = useContext(ClientContext); + const { IS_DEV_MODE } = config; return ( @@ -16,6 +19,13 @@ export const AppBar = () => { + {IS_DEV_MODE && ( + + + + + + )} Promise; handleShowSettings: () => void; handleShowAdmin: () => void; + handleShowTerminal: () => void; logIn: (opts: { type: 'mnemonic' | 'password'; value: string }) => void; signInWithPassword: (password: string) => void; logOut: () => void; @@ -53,6 +55,7 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode const [currency, setCurrency] = useState(); const [showAdmin, setShowAdmin] = useState(false); const [showSettings, setShowSettings] = useState(false); + const [showTerminal, setShowTerminal] = useState(false); const [mode] = useState<'light' | 'dark'>('light'); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(); @@ -128,6 +131,7 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode const handleShowAdmin = () => setShowAdmin((show) => !show); const handleShowSettings = () => setShowSettings((show) => !show); + const handleShowTerminal = () => setShowTerminal((show) => !show); const switchNetwork = (_network: Network) => setNetwork(_network); const memoizedValue = useMemo( @@ -140,6 +144,7 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode userBalance, showAdmin, showSettings, + showTerminal, network, currency, setIsLoading, @@ -149,10 +154,23 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode getBondDetails, handleShowSettings, handleShowAdmin, + handleShowTerminal, logIn, logOut, }), - [mode, isLoading, error, clientDetails, mixnodeDetails, userBalance, showAdmin, showSettings, network, currency], + [ + mode, + isLoading, + error, + clientDetails, + mixnodeDetails, + userBalance, + showAdmin, + showSettings, + showTerminal, + network, + currency, + ], ); return {children}; diff --git a/nym-wallet/src/index.tsx b/nym-wallet/src/index.tsx index 2400a8b00a..78b7190634 100644 --- a/nym-wallet/src/index.tsx +++ b/nym-wallet/src/index.tsx @@ -11,6 +11,7 @@ import { ErrorFallback } from './components'; import { NymWalletTheme, WelcomeTheme } from './theme'; import { maximizeWindow } from './utils'; import { SignInProvider } from './pages/sign-in/context'; +import { Terminal } from './pages/terminal'; const App = () => { const { clientDetails } = useContext(ClientContext); @@ -30,6 +31,7 @@ const App = () => { + diff --git a/nym-wallet/src/pages/terminal/index.tsx b/nym-wallet/src/pages/terminal/index.tsx new file mode 100644 index 0000000000..b0a874fce1 --- /dev/null +++ b/nym-wallet/src/pages/terminal/index.tsx @@ -0,0 +1,167 @@ +import React, { useContext, useState } from 'react'; +import { Alert, Box, Dialog, Paper, Typography } from '@mui/material'; +import TerminalIcon from '@mui/icons-material/Terminal'; +import RefreshIcon from '@mui/icons-material/Refresh'; +import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown'; +import ArrowDropUpIcon from '@mui/icons-material/ArrowDropUp'; +import { ClientContext } from '../../context/main'; +import { NymCard } from '../../components'; +import { getCurrentEpoch, getPendingDelegations, getReverseMixDelegations } from '../../requests'; +import { useGetBalance } from '../../hooks/useGetBalance'; + +const TerminalSection: React.FC<{ + heading: React.ReactNode; +}> = ({ heading, children }) => { + const [isCollapsed, setIsCollapsed] = useState(true); + + const toggleCollapse = () => { + setIsCollapsed((prev) => !prev); + }; + + return ( + + + {isCollapsed ? : } + + {heading} + + + {!isCollapsed && {children}} + + ); +}; + +export const Terminal: React.FC = () => { + const { userBalance, clientDetails, showTerminal, handleShowTerminal } = useContext(ClientContext); + const { balance, vestingAccountInfo, currentVestingPeriod, originalVesting, fetchBalance, fetchTokenAllocation } = + useGetBalance(clientDetails?.client_address); + const [mixnodeDelegations, setMixnodeDelegations] = useState(); + const [pendingEvents, setPendingEvents] = useState(); + const [epoch, setEpoch] = useState(); + const [isBusy, setIsBusy] = useState(); + const [error, setError] = useState(); + const [status, setStatus] = useState(); + + const withErrorCatch = async (fn: () => Promise) => { + try { + await fn(); + } catch (e) { + setError(e); + } + }; + + const refresh = async () => { + setError(undefined); + setIsBusy(true); + setStatus('Getting reverse mix delegations...'); + await withErrorCatch(async () => { + setMixnodeDelegations(await getReverseMixDelegations()); + }); + setStatus('Getting pending delegations...'); + await withErrorCatch(async () => { + setPendingEvents(await getPendingDelegations()); + }); + setStatus('Getting current epoch...'); + await withErrorCatch(async () => { + setEpoch(await getCurrentEpoch()); + }); + setStatus('Fetching balance...'); + await withErrorCatch(async () => { + await fetchBalance(); + }); + setStatus('Fetching token allocation...'); + await withErrorCatch(async () => { + await fetchTokenAllocation(); + }); + setStatus(undefined); + setIsBusy(false); + }; + + React.useEffect(() => { + refresh(); + }, []); + + if (!showTerminal) { + return null; + } + + return ( + + + + Terminal + {!isBusy && } + + } + > + {error && {error}} + + {status ? ( + + {status} + + ) : ( + + Data loading complete + + )} + + +
{JSON.stringify(clientDetails, null, 2)}
+
+ + +
{JSON.stringify(userBalance, null, 2)}
+
+ + + useGetBalance Balance + + } + > +
{JSON.stringify(balance, null, 2)}
+
+ + + useGetBalance Vesting Account Info + + } + > +
{JSON.stringify(vestingAccountInfo, null, 2)}
+
+ + + useGetBalance Current Vest Period + + } + > +
{JSON.stringify(currentVestingPeriod, null, 2)}
+
+ + +
{JSON.stringify(originalVesting, null, 2)}
+
+ + +
{JSON.stringify(mixnodeDelegations, null, 2)}
+
+ + +
{JSON.stringify(pendingEvents, null, 2)}
+
+ + +
{JSON.stringify(epoch, null, 2)}
+
+
+
+ ); +};