Small fixes

This commit is contained in:
Reckless_Satoshi 2023-02-20 12:36:38 -08:00
parent b98c7a1e9f
commit 766666f8ef
No known key found for this signature in database
GPG Key ID: 9C4585B561315571
4 changed files with 299 additions and 649 deletions

View File

@ -12,6 +12,9 @@ import {
Link, Link,
Typography, Typography,
useTheme, useTheme,
Accordion,
AccordionSummary,
AccordionDetails,
} from '@mui/material'; } from '@mui/material';
import { Page } from '../NavBar'; import { Page } from '../NavBar';
import { Robot } from '../../models'; import { Robot } from '../../models';
@ -65,252 +68,231 @@ const Onboarding = ({
}; };
return ( return (
<Grid container direction='column' alignItems='center' spacing={2} padding={2}> <Box>
<Grid item> <Accordion expanded={step === '1'} disableGutters={true}>
<Typography variant='h5' color={step == '1' ? 'text.primary' : 'text.disabled'}> <AccordionSummary>
{t('1. Generate a token')} <Typography variant='h5' color={step == '1' ? 'text.primary' : 'text.disabled'}>
</Typography> {t('1. Generate a token')}
<Box </Typography>
sx={{ </AccordionSummary>
backgroundColor: 'background.paper', <AccordionDetails>
border: '1px solid', <Grid container direction='column' alignItems='center' spacing={1} padding={1}>
borderRadius: '4px', <Grid item>
borderColor: theme.palette.mode === 'dark' ? '#434343' : '#c4c4c4', <Typography>
}} {t(
> 'This temporary key gives you access to a unique and private robot identity for your trade.',
<Collapse in={step == '1'}> )}
<Grid container direction='column' alignItems='center' spacing={1} padding={1.5}> </Typography>
<Grid item>
<Typography>
{t(
'This temporary key gives you access to a unique and private robot identity for your trade.',
)}
</Typography>
</Grid>
{!generatedToken ? (
<Grid item>
<Button autoFocus onClick={generateToken} variant='contained' size='large'>
<Casino />
{t('Generate token')}
</Button>
</Grid>
) : (
<Grid item>
<Collapse in={generatedToken}>
<Grid container direction='column' alignItems='center' spacing={1}>
<Grid item>
<Alert variant='outlined' severity='info'>
<b>{`${t('Store it somewhere safe!')} `}</b>
{t(
`This token is the one and only key to your robot and trade. You will need it later to recover your order or check its status.`,
)}
</Alert>
</Grid>
<Grid item sx={{ width: '100%' }}>
{showMimickProgress ? (
<LinearProgress sx={{ height: '0.7em' }} />
) : (
<TokenInput
inputToken={inputToken}
setInputToken={setInputToken}
setRobot={setRobot}
badRequest={badRequest}
robot={robot}
onPressEnter={() => null}
/>
)}
</Grid>
<Grid item>
<Typography>
{t('You can also add your own random characters into the token or')}
<Button size='small' onClick={generateToken}>
<Casino />
{t('roll again')}
</Button>
</Typography>
</Grid>
<Grid item>
<Button
onClick={() => {
setStep('2');
getGenerateRobot(inputToken);
setRobot({ ...robot, nickname: undefined });
}}
variant='contained'
size='large'
>
<Check />
{t('Continue')}
</Button>
</Grid>
</Grid>
</Collapse>
</Grid>
)}
</Grid> </Grid>
</Collapse> {!generatedToken ? (
</Box>
</Grid>
<Grid item sx={{ width: '100%' }}>
<Typography variant='h5' color={step == '2' ? 'text.primary' : 'text.disabled'}>
{t('2. Meet your robot identity')}
</Typography>
<Box
sx={{
backgroundColor: 'background.paper',
border: '1px solid',
borderRadius: '4px',
borderColor: theme.palette.mode === 'dark' ? '#434343' : '#c4c4c4',
}}
>
<Collapse in={step == '2'}>
<Grid container direction='column' alignItems='center' spacing={1} padding={1.5}>
<Grid item> <Grid item>
<Typography> <Button autoFocus onClick={generateToken} variant='contained' size='large'>
{robot.avatarLoaded && robot.nickname ? ( <Casino />
t('This is your trading avatar') {t('Generate token')}
) : (
<>
<b>{t('Building your robot!')}</b>
<LinearProgress />
</>
)}
</Typography>
</Grid>
<Grid item sx={{ width: '13.5em' }}>
<RobotAvatar
nickname={robot.nickname}
smooth={true}
style={{ maxWidth: '12.5em', maxHeight: '12.5em' }}
placeholderType='generating'
imageStyle={{
transform: '',
border: '2px solid #555',
filter: 'drop-shadow(1px 1px 1px #000000)',
height: '12.4em',
width: '12.4em',
}}
tooltipPosition='top'
baseUrl={baseUrl}
/>
</Grid>
{robot.avatarLoaded && robot.nickname ? (
<Grid item>
<Typography align='center'>{t('Hi! My name is')}</Typography>
<Typography component='h5' variant='h5'>
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexWrap: 'wrap',
}}
>
<Bolt
sx={{
color: '#fcba03',
height: '1.5em',
width: '1.5em',
}}
/>
<b>{robot.nickname}</b>
<Bolt
sx={{
color: '#fcba03',
height: '1.5em',
width: '1.5em',
}}
/>
</div>
</Typography>
</Grid>
) : null}
<Grid item>
<Collapse in={robot.avatarLoaded && robot.nickname ? true : false}>
<Button onClick={() => setStep('3')} variant='contained' size='large'>
<Check />
{t('Continue')}
</Button>
</Collapse>
</Grid>
</Grid>
</Collapse>
</Box>
</Grid>
<Grid item>
<Typography variant='h5' color={step == '3' ? 'text.primary' : 'text.disabled'}>
{t('3. Browse or create an order')}
</Typography>
<Box
sx={{
backgroundColor: 'background.paper',
border: '1px solid',
borderRadius: '4px',
borderColor: theme.palette.mode === 'dark' ? '#434343' : '#c4c4c4',
}}
>
<Collapse in={step == '3'}>
<Grid container direction='column' alignItems='center' spacing={1} padding={1.5}>
<Grid item>
<Typography>
{t(
'RoboSats is a peer-to-peer marketplace. You can browse the public offers or create a new one.',
)}
</Typography>
</Grid>
<Grid item>
<ButtonGroup variant='contained'>
<Button color='primary' onClick={() => changePage('offers')}>
<Storefront /> <div style={{ width: '0.5em' }} />
{t('Offers')}
</Button>
<Button color='secondary' onClick={() => changePage('create')}>
<AddBox /> <div style={{ width: '0.5em' }} />
{t('Create')}
</Button>
</ButtonGroup>
</Grid>
<Grid item>
<Typography>
{`${t('If you need help on your RoboSats journey join our public support')} `}
<Link target='_blank' href='https://t.me/robosats_es' rel='noreferrer'>
{t('Telegram group')}
</Link>
{`, ${t('or visit the robot school for documentation.')} `}
</Typography>
</Grid>
<Grid item>
<Button
sx={{ color: 'black' }}
component={Link}
href='https://learn.robosats.com'
target='_blank'
color='inherit'
variant='contained'
>
<School /> <div style={{ width: '0.5em' }} />
{t('Learn RoboSats')}
<div style={{ width: '0.5em' }} />
<NewTabIcon sx={{ width: '0.8em' }} />
</Button> </Button>
</Grid> </Grid>
) : (
<Grid item>
<Collapse in={generatedToken}>
<Grid container direction='column' alignItems='center' spacing={1}>
<Grid item>
<Alert variant='outlined' severity='info'>
<b>{`${t('Store it somewhere safe!')} `}</b>
{t(
`This token is the one and only key to your robot and trade. You will need it later to recover your order or check its status.`,
)}
</Alert>
</Grid>
<Grid item sx={{ width: '100%' }}>
{showMimickProgress ? (
<LinearProgress sx={{ height: '0.7em' }} />
) : (
<TokenInput
inputToken={inputToken}
setInputToken={setInputToken}
setRobot={setRobot}
badRequest={badRequest}
robot={robot}
onPressEnter={() => null}
/>
)}
</Grid>
<Grid item>
<Typography>
{t('You can also add your own random characters into the token or')}
<Button size='small' onClick={generateToken}>
<Casino />
{t('roll again')}
</Button>
</Typography>
</Grid>
<Grid item>
<Button
onClick={() => {
setStep('2');
getGenerateRobot(inputToken);
setRobot({ ...robot, nickname: undefined });
}}
variant='contained'
size='large'
>
<Check />
{t('Continue')}
</Button>
</Grid>
</Grid>
</Collapse>
</Grid>
)}
</Grid>
</AccordionDetails>
</Accordion>
<Accordion expanded={step === '2'} disableGutters={true}>
<AccordionSummary>
<Typography variant='h5' color={step == '2' ? 'text.primary' : 'text.disabled'}>
{t('2. Meet your robot identity')}
</Typography>
</AccordionSummary>
<AccordionDetails>
<Grid container direction='column' alignItems='center' spacing={1}>
<Grid item>
<Typography>
{robot.avatarLoaded && robot.nickname ? (
t('This is your trading avatar')
) : (
<>
<b>{t('Building your robot!')}</b>
<LinearProgress />
</>
)}
</Typography>
</Grid> </Grid>
</Collapse>
</Box> <Grid item sx={{ width: '13.5em' }}>
</Grid> <RobotAvatar
<Grid item> nickname={robot.nickname}
<Button color='inherit' onClick={() => setView('profile')}> smooth={true}
{t('See profile')} style={{ maxWidth: '12.5em', maxHeight: '12.5em' }}
</Button> placeholderType='generating'
</Grid> imageStyle={{
</Grid> transform: '',
border: '2px solid #555',
filter: 'drop-shadow(1px 1px 1px #000000)',
height: '12.4em',
width: '12.4em',
}}
tooltipPosition='top'
baseUrl={baseUrl}
/>
</Grid>
{robot.avatarLoaded && robot.nickname ? (
<Grid item>
<Typography align='center'>{t('Hi! My name is')}</Typography>
<Typography component='h5' variant='h5'>
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexWrap: 'wrap',
}}
>
<Bolt
sx={{
color: '#fcba03',
height: '1.5em',
width: '1.5em',
}}
/>
<b>{robot.nickname}</b>
<Bolt
sx={{
color: '#fcba03',
height: '1.5em',
width: '1.5em',
}}
/>
</div>
</Typography>
</Grid>
) : null}
<Grid item>
<Collapse in={robot.avatarLoaded && robot.nickname ? true : false}>
<Button onClick={() => setStep('3')} variant='contained' size='large'>
<Check />
{t('Continue')}
</Button>
</Collapse>
</Grid>
</Grid>
</AccordionDetails>
</Accordion>
<Accordion expanded={step === '3'} disableGutters={true}>
<AccordionSummary>
<Typography variant='h5' color={step == '3' ? 'text.primary' : 'text.disabled'}>
{t('3. Browse or create an order')}
</Typography>
</AccordionSummary>
<AccordionDetails>
<Grid container direction='column' alignItems='center' spacing={1} padding={1.5}>
<Grid item>
<Typography>
{t(
'RoboSats is a peer-to-peer marketplace. You can browse the public offers or create a new one.',
)}
</Typography>
</Grid>
<Grid item>
<ButtonGroup variant='contained'>
<Button color='primary' onClick={() => changePage('offers')}>
<Storefront /> <div style={{ width: '0.5em' }} />
{t('Offers')}
</Button>
<Button color='secondary' onClick={() => changePage('create')}>
<AddBox /> <div style={{ width: '0.5em' }} />
{t('Create')}
</Button>
</ButtonGroup>
</Grid>
<Grid item>
<Typography>
{`${t('If you need help on your RoboSats journey join our public support')} `}
<Link target='_blank' href='https://t.me/robosats_es' rel='noreferrer'>
{t('Telegram group')}
</Link>
{`, ${t('or visit the robot school for documentation.')} `}
</Typography>
</Grid>
<Grid item>
<Button
sx={{ color: 'black' }}
component={Link}
href='https://learn.robosats.com'
target='_blank'
color='inherit'
variant='contained'
>
<School /> <div style={{ width: '0.5em' }} />
{t('Learn RoboSats')}
<div style={{ width: '0.5em' }} />
<NewTabIcon sx={{ width: '0.8em' }} />
</Button>
</Grid>
<Grid item sx={{ position: 'relative', top: '0.6em' }}>
<Button color='inherit' onClick={() => setView('profile')}>
{t('See profile')}
</Button>
</Grid>
</Grid>
</AccordionDetails>
</Accordion>
</Box>
); );
}; };

View File

@ -1,17 +1,20 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Button, Grid, LinearProgress, Typography, useTheme } from '@mui/material'; import { useHistory } from 'react-router-dom';
import { Bolt, Logout } from '@mui/icons-material'; import { Button, Link, Grid, LinearProgress, Typography, Alert } from '@mui/material';
import { Bolt, Logout, Refresh } from '@mui/icons-material';
import RobotAvatar from '../../components/RobotAvatar'; import RobotAvatar from '../../components/RobotAvatar';
import TokenInput from './TokenInput'; import TokenInput from './TokenInput';
import { Page } from '../NavBar'; import { Page } from '../NavBar';
import { Robot } from '../../models'; import { Robot } from '../../models';
import { genBase62Token } from '../../utils';
interface RobotProfileProps { interface RobotProfileProps {
robot: Robot; robot: Robot;
setRobot: (state: Robot) => void; setRobot: (state: Robot) => void;
setView: (state: 'welcome' | 'onboarding' | 'recovery' | 'profile') => void; setView: (state: 'welcome' | 'onboarding' | 'recovery' | 'profile') => void;
inputToken: string; inputToken: string;
setCurrentOrder: (state: number) => void;
logoutRobot: () => void; logoutRobot: () => void;
setInputToken: (state: string) => void; setInputToken: (state: string) => void;
getGenerateRobot: (token: string) => void; getGenerateRobot: (token: string) => void;
@ -27,7 +30,10 @@ const RobotProfile = ({
setRobot, setRobot,
inputToken, inputToken,
setInputToken, setInputToken,
setCurrentOrder,
getGenerateRobot,
logoutRobot, logoutRobot,
setPage,
setView, setView,
badRequest, badRequest,
baseUrl, baseUrl,
@ -35,7 +41,12 @@ const RobotProfile = ({
width, width,
}: RobotProfileProps): JSX.Element => { }: RobotProfileProps): JSX.Element => {
const { t } = useTranslation(); const { t } = useTranslation();
const theme = useTheme(); const history = useHistory();
const getNewRobot = () => {
logoutRobot();
setTimeout(() => getGenerateRobot(genBase62Token(36)), 10);
};
return ( return (
<Grid container direction='column' alignItems='center' spacing={2} padding={2}> <Grid container direction='column' alignItems='center' spacing={2} padding={2}>
@ -73,7 +84,7 @@ const RobotProfile = ({
</Typography> </Typography>
) : ( ) : (
<> <>
<b>{t('Rebuilding your robot!')}</b> <b>{t('Building your robot!')}</b>
<LinearProgress /> <LinearProgress />
</> </>
)} )}
@ -102,18 +113,60 @@ const RobotProfile = ({
<Grid item> <Grid item>
<Typography variant='subtitle2' color='primary'> <Typography variant='subtitle2' color='primary'>
{t('Welcome back!')} {t('Welcome back!')}
<br />
</Typography> </Typography>
</Grid> </Grid>
) : ( ) : (
<></> <></>
)} )}
<Grid item> {robot.activeOrderId ? (
{/* This robot has an active order <Grid item>
<Typography>
{t('One active order')}
<Link
onClick={() => {
history.push('/order/' + robot.activeOrderId);
setPage('order');
setCurrentOrder(robot.activeOrderId);
}}
>
{` #${robot.activeOrderId}`}
</Link>
</Typography>
</Grid>
) : null}
This robot has a past order. Reusing Robot degrades your privacy: Get a new robot! */} {robot.lastOrderId ? (
</Grid> <Grid item>
<Typography align='center'>
{t('Your past order')}
<Link
onClick={() => {
history.push('/order/' + robot.lastOrderId);
setPage('order');
setCurrentOrder(robot.lastOrderId);
}}
>
{` #${robot.lastOrderId}`}
</Link>
</Typography>
<Alert severity='warning'>
<Grid container direction='column' alignItems='center'>
<Grid item>
{t(
'Reusing trading identity degrades your privacy against other users, coordinators and observers.',
)}
</Grid>
<Grid item sx={{ position: 'relative', right: '1em' }}>
<Button color='inherit' size='small' onClick={getNewRobot}>
<Refresh />
{t('Generate a new Robot')}
</Button>
</Grid>
</Grid>
</Alert>
</Grid>
) : null}
<Grid item sx={{ width: '100%' }}> <Grid item sx={{ width: '100%' }}>
<TokenInput <TokenInput

View File

@ -1,6 +1,15 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Paper, Grid, CircularProgress, Box, Alert, Typography, useTheme } from '@mui/material'; import {
Paper,
Grid,
CircularProgress,
Box,
Alert,
Typography,
useTheme,
AlertTitle,
} from '@mui/material';
import { useParams } from 'react-router-dom'; import { useParams } from 'react-router-dom';
import { Page } from '../NavBar'; import { Page } from '../NavBar';
@ -134,13 +143,13 @@ const RobotPage = ({
}; };
const logoutRobot = () => { const logoutRobot = () => {
setRobot({ ...robot, nickname: undefined, token: undefined, avatarLoaded: false });
setInputToken(''); setInputToken('');
setRobotFound(false); setRobotFound(false);
systemClient.deleteCookie('sessionid'); systemClient.deleteCookie('sessionid');
systemClient.deleteItem('robot_token'); systemClient.deleteItem('robot_token');
systemClient.deleteItem('pub_key'); systemClient.deleteItem('pub_key');
systemClient.deleteItem('enc_priv_key'); systemClient.deleteItem('enc_priv_key');
setTimeout(() => setRobot(new Robot()), 10);
}; };
if (window?.NativeRobosats & (torStatus != 'DONE')) { if (window?.NativeRobosats & (torStatus != 'DONE')) {
@ -154,7 +163,7 @@ const RobotPage = ({
> >
<Grid container direction='column' alignItems='center' spacing={1} padding={2}> <Grid container direction='column' alignItems='center' spacing={1} padding={2}>
<Grid item> <Grid item>
<Typography align='center' variant='h5'> <Typography align='center' variant='h6'>
{t('Connecting to TOR')} {t('Connecting to TOR')}
</Typography> </Typography>
</Grid> </Grid>
@ -182,7 +191,7 @@ const RobotPage = ({
</Grid> </Grid>
<Grid item> <Grid item>
<Alert> <Alert>
<b>{t('Your traffic is encrypted and annonimized using TOR. ')}</b> <AlertTitle>{t('Connection encrypted and anonymized using TOR.')}</AlertTitle>
{t( {t(
'This ensures maximum privacy, however you might feel the app behaves slow. If connection is lost, restart the app.', 'This ensures maximum privacy, however you might feel the app behaves slow. If connection is lost, restart the app.',
)} )}
@ -226,6 +235,7 @@ const RobotPage = ({
robot={robot} robot={robot}
robotFound={robotFound} robotFound={robotFound}
setRobot={setRobot} setRobot={setRobot}
setCurrentOrder={setCurrentOrder}
badRequest={badRequest} badRequest={badRequest}
logoutRobot={logoutRobot} logoutRobot={logoutRobot}
width={width} width={width}

View File

@ -1,395 +0,0 @@
import React, { Component } from 'react';
import { withTranslation } from 'react-i18next';
import {
Button,
Tooltip,
Grid,
Typography,
TextField,
ButtonGroup,
CircularProgress,
IconButton,
} from '@mui/material';
import SmartToyIcon from '@mui/icons-material/SmartToy';
import CasinoIcon from '@mui/icons-material/Casino';
import ContentCopy from '@mui/icons-material/ContentCopy';
import BoltIcon from '@mui/icons-material/Bolt';
import DownloadIcon from '@mui/icons-material/Download';
import { RoboSatsNoTextIcon } from '../components/Icons';
import { sha256 } from 'js-sha256';
import { genBase62Token, tokenStrength, saveAsJson } from '../utils';
import { genKey } from '../pgp';
import { systemClient } from '../services/System';
import { apiClient } from '../services/api/index';
import RobotAvatar from '../components/RobotAvatar';
class UserGenPage extends Component {
constructor(props) {
super(props);
this.state = {
tokenHasChanged: false,
inputToken: '',
found: false,
};
this.refCode = this.props.match.params.refCode;
}
componentDidMount() {
// Checks in parent HomePage if there is already a nick and token
// Displays the existing one
if (this.props.robot.nickname != null) {
this.setState({ inputToken: this.props.robot.token });
} else if (this.props.robot.token) {
this.setState({ inputToken: this.props.robot.token });
this.getGeneratedUser(this.props.robot.token);
} else {
const newToken = genBase62Token(36);
this.setState({
inputToken: newToken,
});
this.getGeneratedUser(newToken);
}
}
getGeneratedUser = (token) => {
const strength = tokenStrength(token);
const refCode = this.refCode;
this.props.setRobot({ ...this.props.robot, loading: true, avatarLoaded: false });
const requestBody = genKey(token).then(function (key) {
return {
token_sha256: sha256(token),
public_key: key.publicKeyArmored,
encrypted_private_key: key.encryptedPrivateKeyArmored,
unique_values: strength.uniqueValues,
counts: strength.counts,
length: token.length,
ref_code: refCode,
};
});
requestBody.then((body) =>
apiClient.post(this.props.baseUrl, '/api/user/', body).then((data) => {
this.setState({ found: data.found, bad_request: data.bad_request });
this.props.setCurrentOrder(
data.active_order_id
? data.active_order_id
: data.last_order_id
? data.last_order_id
: null,
);
// Add nick and token to App state (token only if not a bad request)
data.bad_request
? this.props.setRobot({
...this.props.robot,
avatarLoaded: true,
loading: false,
nickname: data.nickname ?? this.props.robot.nickname,
activeOrderId: data.active_order_id ?? null,
referralCode: data.referral_code ?? this.props.referralCode,
earnedRewards: data.earned_rewards ?? this.props.earnedRewards,
lastOrderId: data.last_order_id ?? this.props.lastOrderId,
stealthInvoices: data.wants_stealth ?? this.props.stealthInvoices,
tgEnabled: data.tg_enabled,
tgBotName: data.tg_bot_name,
tgToken: data.tg_token,
})
: this.props.setRobot({
...this.props.robot,
nickname: data.nickname,
token,
loading: false,
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 : this.props.robot.copiedToken,
}) &
systemClient.setItem('robot_token', token) &
systemClient.setItem('pub_key', data.public_key.split('\n').join('\\')) &
systemClient.setItem('enc_priv_key', data.encrypted_private_key.split('\n').join('\\'));
}),
);
};
delGeneratedUser() {
apiClient.delete(this.props.baseUrl, '/api/user');
systemClient.deleteCookie('sessionid');
systemClient.deleteItem('robot_token');
systemClient.deleteItem('pub_key');
systemClient.deleteItem('enc_priv_key');
}
handleClickNewRandomToken = () => {
const inputToken = genBase62Token(36);
this.setState({
inputToken,
tokenHasChanged: true,
});
this.props.setRobot({ ...this.props.robot, copiedToken: true });
};
handleChangeToken = (e) => {
this.setState({
inputToken: e.target.value.split(' ').join(''),
tokenHasChanged: true,
});
};
handleClickSubmitToken = () => {
this.delGeneratedUser();
this.getGeneratedUser(this.state.inputToken);
this.setState({ tokenHasChanged: false });
this.props.setRobot({
...this.props.robot,
avatarLoaded: false,
nickname: null,
token: null,
copiedToken: false,
lastOrderId: null,
activeOrderId: null,
});
};
createJsonFile = () => {
return {
token: this.props.robot.token,
token_shannon_entropy: this.props.robot.shannonEntropy,
token_bit_entropy: this.props.robot.bitsEntropy,
public_key: this.props.robot.pub_key,
encrypted_private_key: this.props.robot.enc_priv_key,
};
};
render() {
const { t, i18n } = this.props;
const fontSize = this.props.theme.typography.fontSize;
const fontSizeFactor = fontSize / 14; // to scale sizes, default fontSize is 14
return (
<Grid container spacing={1}>
<Grid item>
<div className='clickTrough' />
</Grid>
<Grid
item
xs={12}
align='center'
sx={{ width: 370 * fontSizeFactor, height: 260 * fontSizeFactor }}
>
{this.props.robot.avatarLoaded && this.props.robot.nickname ? (
<div>
<Grid item xs={12} align='center'>
<Typography component='h5' variant='h5'>
<b>
{this.props.robot.nickname && systemClient.getCookie('sessionid') ? (
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexWrap: 'wrap',
height: 45 * fontSizeFactor,
}}
>
<BoltIcon
sx={{
color: '#fcba03',
height: 33 * fontSizeFactor,
width: 33 * fontSizeFactor,
}}
/>
<a>{this.props.robot.nickname}</a>
<BoltIcon
sx={{
color: '#fcba03',
height: 33 * fontSizeFactor,
width: 33 * fontSizeFactor,
}}
/>
</div>
) : (
''
)}
</b>
</Typography>
</Grid>
<Grid item xs={12} align='center'>
<RobotAvatar
nickname={this.props.robot.nickname}
smooth={true}
style={{ maxWidth: 203 * fontSizeFactor, maxHeight: 203 * fontSizeFactor }}
imageStyle={{
transform: '',
border: '2px solid #555',
filter: 'drop-shadow(1px 1px 1px #000000)',
height: `${201 * fontSizeFactor}px`,
width: `${201 * fontSizeFactor}px`,
}}
tooltip={t('This is your trading avatar')}
tooltipPosition='top'
baseUrl={this.props.baseUrl}
/>
<br />
</Grid>
</div>
) : (
<CircularProgress sx={{ position: 'relative', top: 100 }} />
)}
</Grid>
{this.state.found ? (
<Grid item xs={12} align='center'>
<Typography variant='subtitle2' color='primary'>
{this.state.found ? t('A robot avatar was found, welcome back!') : null}
<br />
</Typography>
</Grid>
) : (
''
)}
<Grid container align='center'>
<Grid item xs={12} align='center'>
<TextField
sx={{ maxWidth: 280 * fontSizeFactor }}
error={!!this.state.bad_request}
label={t('Store your token safely')}
required={true}
value={this.state.inputToken}
variant='standard'
helperText={this.state.bad_request}
size='small'
onChange={this.handleChangeToken}
onKeyPress={(e) => {
if (e.key === 'Enter') {
this.handleClickSubmitToken();
}
}}
InputProps={{
startAdornment: (
<div
style={{
width: 50 * fontSizeFactor,
minWidth: 50 * fontSizeFactor,
position: 'relative',
left: -6,
}}
>
<Grid container>
<Grid item xs={6}>
<Tooltip
enterTouchDelay={250}
title={t('Save token and PGP credentials to file')}
>
<span>
<IconButton
color='primary'
disabled={
!this.props.robot.avatarLoaded ||
!(systemClient.getItem('robot_token') == this.state.inputToken)
}
onClick={() =>
saveAsJson(
this.props.robot.nickname + '.json',
this.createJsonFile(),
)
}
>
<DownloadIcon
sx={{ width: 22 * fontSizeFactor, height: 22 * fontSizeFactor }}
/>
</IconButton>
</span>
</Tooltip>
</Grid>
<Grid item xs={6}>
<Tooltip disableHoverListener enterTouchDelay={0} title={t('Copied!')}>
<IconButton
color={this.props.robot.copiedToken ? 'inherit' : 'primary'}
disabled={
!this.props.robot.avatarLoaded ||
!(systemClient.getItem('robot_token') === this.state.inputToken)
}
onClick={() =>
systemClient.copyToClipboard(systemClient.getItem('robot_token')) &
this.props.setRobot({ ...this.props.robot, copiedToken: true })
}
>
<ContentCopy
sx={{ width: 18 * fontSizeFactor, height: 18 * fontSizeFactor }}
/>
</IconButton>
</Tooltip>
</Grid>
</Grid>
</div>
),
endAdornment: (
<Tooltip enterTouchDelay={250} title={t('Generate a new token')}>
<IconButton onClick={this.handleClickNewRandomToken}>
<CasinoIcon
sx={{ width: 18 * fontSizeFactor, height: 18 * fontSizeFactor }}
/>
</IconButton>
</Tooltip>
),
}}
/>
</Grid>
</Grid>
<Grid item xs={12} align='center'>
{this.state.tokenHasChanged ? (
<Button type='submit' size='small' onClick={this.handleClickSubmitToken}>
<SmartToyIcon sx={{ width: 18 * fontSizeFactor, height: 18 * fontSizeFactor }} />
<span> {t('Generate Robot')}</span>
</Button>
) : (
<Tooltip
enterTouchDelay={0}
enterDelay={500}
enterNextDelay={2000}
title={t('You must enter a new token first')}
>
<div>
<Button disabled={true} type='submit' size='small'>
<SmartToyIcon sx={{ width: 18 * fontSizeFactor, height: 18 * fontSizeFactor }} />
<span>{t('Generate Robot')}</span>
</Button>
</div>
</Tooltip>
)}
</Grid>
<Grid item xs={12} align='center' sx={{ width: '26.43em' }}>
<Grid item>
<div style={{ height: '2.143em' }} />
</Grid>
<div style={{ width: '26.43em', left: '2.143em' }}>
<Grid container align='center'>
<Grid item xs={0.8} />
<Grid item xs={7.5} align='right'>
<Typography component='h5' variant='h5'>
{t('Simple and Private LN P2P Exchange')}
</Typography>
</Grid>
<Grid item xs={2.5} align='left'>
<RoboSatsNoTextIcon color='primary' sx={{ height: '3.143em', width: '3.143em' }} />
</Grid>
</Grid>
</div>
</Grid>
</Grid>
);
}
}
export default withTranslation()(UserGenPage);