2022-01-02 00:19:18 +00:00
|
|
|
import React, { Component } from "react";
|
2022-02-01 22:05:49 +00:00
|
|
|
import { Button , Tooltip, Dialog, Grid, Typography, TextField, ButtonGroup, CircularProgress, IconButton} from "@mui/material"
|
2022-01-02 21:41:22 +00:00
|
|
|
import { Link } from 'react-router-dom'
|
|
|
|
import Image from 'material-ui-image'
|
2022-01-15 00:28:19 +00:00
|
|
|
import InfoDialog from './InfoDialog'
|
2022-01-30 15:18:03 +00:00
|
|
|
import SmartToyIcon from '@mui/icons-material/SmartToy';
|
2022-01-30 13:18:32 +00:00
|
|
|
import CasinoIcon from '@mui/icons-material/Casino';
|
2022-01-18 13:20:19 +00:00
|
|
|
import ContentCopy from "@mui/icons-material/ContentCopy";
|
2022-01-02 00:19:18 +00:00
|
|
|
|
2022-01-03 01:31:28 +00:00
|
|
|
function getCookie(name) {
|
|
|
|
let cookieValue = null;
|
|
|
|
if (document.cookie && document.cookie !== '') {
|
|
|
|
const cookies = document.cookie.split(';');
|
|
|
|
for (let i = 0; i < cookies.length; i++) {
|
|
|
|
const cookie = cookies[i].trim();
|
|
|
|
// Does this cookie string begin with the name we want?
|
|
|
|
if (cookie.substring(0, name.length + 1) === (name + '=')) {
|
|
|
|
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return cookieValue;
|
|
|
|
}
|
|
|
|
const csrftoken = getCookie('csrftoken');
|
|
|
|
|
2022-01-02 15:19:49 +00:00
|
|
|
export default class UserGenPage extends Component {
|
2022-01-02 17:42:33 +00:00
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
this.state = {
|
2022-01-15 00:28:19 +00:00
|
|
|
openInfo: false,
|
2022-01-30 13:18:32 +00:00
|
|
|
tokenHasChanged: false,
|
2022-01-02 17:42:33 +00:00
|
|
|
};
|
2022-02-21 10:05:19 +00:00
|
|
|
|
2022-03-05 17:32:27 +00:00
|
|
|
this.refCode = this.props.match.params.refCode;
|
2022-02-21 10:05:19 +00:00
|
|
|
|
|
|
|
// Checks in parent HomePage if there is already a nick and token
|
|
|
|
// Displays the existing one
|
|
|
|
if (this.props.nickname != null){
|
|
|
|
this.state = {
|
|
|
|
nickname: this.props.nickname,
|
|
|
|
token: this.props.token? this.props.token : null,
|
2022-03-05 17:32:27 +00:00
|
|
|
avatar_url: '/static/assets/avatars/' + this.props.nickname + '.png',
|
2022-02-21 10:05:19 +00:00
|
|
|
loadingRobot: false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
var newToken = this.genBase62Token(36)
|
|
|
|
this.state = {
|
|
|
|
token: newToken
|
|
|
|
}
|
|
|
|
this.getGeneratedUser(newToken);
|
|
|
|
}
|
2022-01-02 17:42:33 +00:00
|
|
|
}
|
2022-01-02 18:27:40 +00:00
|
|
|
|
2022-01-02 17:42:33 +00:00
|
|
|
// sort of cryptographically strong function to generate Base62 token client-side
|
|
|
|
genBase62Token(length)
|
|
|
|
{
|
2022-03-05 17:32:27 +00:00
|
|
|
console.log(this.refCode)
|
2022-01-02 17:42:33 +00:00
|
|
|
return window.btoa(Array.from(
|
|
|
|
window.crypto.getRandomValues(
|
|
|
|
new Uint8Array(length * 2)))
|
|
|
|
.map((b) => String.fromCharCode(b))
|
|
|
|
.join("")).replace(/[+/]/g, "")
|
|
|
|
.substring(0, length);
|
|
|
|
}
|
|
|
|
|
2022-01-29 19:51:26 +00:00
|
|
|
getGeneratedUser=(token)=>{
|
2022-01-09 14:43:47 +00:00
|
|
|
fetch('/api/user' + '?token=' + token)
|
2022-01-02 18:27:40 +00:00
|
|
|
.then((response) => response.json())
|
|
|
|
.then((data) => {
|
|
|
|
this.setState({
|
|
|
|
nickname: data.nickname,
|
|
|
|
bit_entropy: data.token_bits_entropy,
|
2022-03-05 17:32:27 +00:00
|
|
|
avatar_url: '/static/assets/avatars/' + data.nickname + '.png',
|
2022-01-02 18:27:40 +00:00
|
|
|
shannon_entropy: data.token_shannon_entropy,
|
|
|
|
bad_request: data.bad_request,
|
2022-01-02 21:41:22 +00:00
|
|
|
found: data.found,
|
2022-01-30 13:18:32 +00:00
|
|
|
loadingRobot:false,
|
2022-01-29 19:51:26 +00:00
|
|
|
})
|
|
|
|
&
|
2022-01-29 20:29:33 +00:00
|
|
|
// Add nick and token to App state (token only if not a bad request)
|
|
|
|
(data.bad_request ? this.props.setAppState({
|
|
|
|
nickname: data.nickname,
|
2022-02-01 19:43:33 +00:00
|
|
|
avatarLoaded: false,
|
2022-01-29 20:29:33 +00:00
|
|
|
})
|
|
|
|
:
|
2022-01-29 19:51:26 +00:00
|
|
|
this.props.setAppState({
|
|
|
|
nickname: data.nickname,
|
2022-01-29 20:17:30 +00:00
|
|
|
token: this.state.token,
|
2022-02-01 19:43:33 +00:00
|
|
|
avatarLoaded: false,
|
2022-01-29 20:29:33 +00:00
|
|
|
}));
|
2022-01-02 18:27:40 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-01-03 01:31:28 +00:00
|
|
|
delGeneratedUser() {
|
|
|
|
const requestOptions = {
|
|
|
|
method: 'DELETE',
|
2022-01-06 12:32:17 +00:00
|
|
|
headers: {'Content-Type':'application/json', 'X-CSRFToken': getCookie('csrftoken')},
|
2022-01-03 01:31:28 +00:00
|
|
|
};
|
2022-01-09 15:24:41 +00:00
|
|
|
fetch("/api/user", requestOptions)
|
2022-01-03 01:31:28 +00:00
|
|
|
.then((response) => response.json())
|
|
|
|
.then((data) => console.log(data));
|
|
|
|
}
|
|
|
|
|
2022-01-30 13:18:32 +00:00
|
|
|
handleClickNewRandomToken=()=>{
|
|
|
|
this.setState({
|
2022-02-08 16:20:41 +00:00
|
|
|
token: this.genBase62Token(36),
|
2022-01-30 13:18:32 +00:00
|
|
|
tokenHasChanged: true,
|
2022-02-02 09:29:05 +00:00
|
|
|
copied: true,
|
2022-01-30 13:18:32 +00:00
|
|
|
});
|
2022-01-02 21:41:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
handleChangeToken=(e)=>{
|
|
|
|
this.setState({
|
|
|
|
token: e.target.value,
|
2022-01-30 13:18:32 +00:00
|
|
|
tokenHasChanged: true,
|
2022-01-02 21:41:22 +00:00
|
|
|
})
|
2022-01-30 13:18:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
handleClickSubmitToken=()=>{
|
2022-02-01 19:43:33 +00:00
|
|
|
this.delGeneratedUser();
|
2022-01-30 13:18:32 +00:00
|
|
|
this.getGeneratedUser(this.state.token);
|
2022-02-01 22:05:49 +00:00
|
|
|
this.setState({loadingRobot: true, tokenHasChanged: false, copied: false});
|
2022-02-01 19:43:33 +00:00
|
|
|
this.props.setAppState({avatarLoaded: false, nickname: null, token: null});
|
2022-01-02 21:41:22 +00:00
|
|
|
}
|
2022-01-02 18:27:40 +00:00
|
|
|
|
2022-01-15 00:28:19 +00:00
|
|
|
handleClickOpenInfo = () => {
|
|
|
|
this.setState({openInfo: true});
|
|
|
|
};
|
|
|
|
|
|
|
|
handleCloseInfo = () => {
|
|
|
|
this.setState({openInfo: false});
|
|
|
|
};
|
|
|
|
|
|
|
|
InfoDialog =() =>{
|
|
|
|
return(
|
|
|
|
<Dialog
|
|
|
|
open={this.state.openInfo}
|
|
|
|
onClose={this.handleCloseInfo}
|
|
|
|
aria-labelledby="info-dialog-title"
|
|
|
|
aria-describedby="info-dialog-description"
|
|
|
|
scroll="paper"
|
|
|
|
>
|
2022-01-30 20:07:13 +00:00
|
|
|
<InfoDialog handleCloseInfo = {this.handleCloseInfo}/>
|
2022-01-15 00:28:19 +00:00
|
|
|
</Dialog>
|
|
|
|
)
|
2022-01-04 15:00:34 +00:00
|
|
|
}
|
|
|
|
|
2022-01-02 17:42:33 +00:00
|
|
|
render() {
|
|
|
|
return (
|
2022-01-02 21:41:22 +00:00
|
|
|
<Grid container spacing={1}>
|
2022-01-30 13:18:32 +00:00
|
|
|
<Grid item xs={12} align="center" sx={{width:370, height:260}}>
|
|
|
|
{!this.state.loadingRobot ?
|
2022-01-18 13:20:19 +00:00
|
|
|
<div>
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<Typography component="h5" variant="h5">
|
|
|
|
<b>{this.state.nickname ? "⚡"+this.state.nickname+"⚡" : ""}</b>
|
|
|
|
</Typography>
|
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="center">
|
2022-02-01 22:05:49 +00:00
|
|
|
<Tooltip enterTouchDelay="0" title="This is your trading avatar">
|
2022-01-18 13:20:19 +00:00
|
|
|
<div style={{ maxWidth: 200, maxHeight: 200 }}>
|
|
|
|
<Image className='newAvatar'
|
|
|
|
disableError='true'
|
|
|
|
cover='true'
|
|
|
|
color='null'
|
|
|
|
src={this.state.avatar_url}
|
|
|
|
/>
|
2022-02-01 22:05:49 +00:00
|
|
|
</div>
|
|
|
|
</Tooltip><br/>
|
2022-01-18 13:20:19 +00:00
|
|
|
</Grid>
|
|
|
|
</div>
|
2022-01-30 13:18:32 +00:00
|
|
|
: <CircularProgress sx={{position: 'relative', top: 100, }}/>}
|
2022-01-02 21:41:22 +00:00
|
|
|
</Grid>
|
|
|
|
{
|
|
|
|
this.state.found ?
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<Typography component="subtitle2" variant="subtitle2" color='primary'>
|
2022-01-03 09:06:51 +00:00
|
|
|
{this.state.found}<br/>
|
2022-01-02 21:41:22 +00:00
|
|
|
</Typography>
|
|
|
|
</Grid>
|
|
|
|
:
|
2022-01-03 14:27:25 +00:00
|
|
|
""
|
2022-01-02 21:41:22 +00:00
|
|
|
}
|
2022-01-18 13:20:19 +00:00
|
|
|
<Grid container align="center">
|
|
|
|
<Grid item xs={12} align="center">
|
2022-01-30 15:18:03 +00:00
|
|
|
<TextField sx={{maxWidth: 280}}
|
2022-01-18 13:20:19 +00:00
|
|
|
//sx={{ input: { color: 'purple' } }}
|
2022-01-30 15:18:03 +00:00
|
|
|
// InputLabelProps={{
|
|
|
|
// style: { color: 'green' },
|
|
|
|
// }}
|
2022-01-18 13:20:19 +00:00
|
|
|
error={this.state.bad_request}
|
2022-02-01 22:05:49 +00:00
|
|
|
label={"Store your token safely"}
|
2022-01-18 13:20:19 +00:00
|
|
|
required='true'
|
|
|
|
value={this.state.token}
|
|
|
|
variant='standard'
|
|
|
|
helperText={this.state.bad_request}
|
|
|
|
size='small'
|
|
|
|
// multiline = {true}
|
|
|
|
onChange={this.handleChangeToken}
|
2022-01-30 13:18:32 +00:00
|
|
|
onKeyPress={(e) => {
|
|
|
|
if (e.key === 'Enter') {
|
|
|
|
this.handleClickSubmitToken();
|
|
|
|
}
|
|
|
|
}}
|
2022-01-30 15:18:03 +00:00
|
|
|
InputProps={{
|
|
|
|
startAdornment:
|
2022-02-01 22:05:49 +00:00
|
|
|
<Tooltip disableHoverListener open={this.state.copied} enterTouchDelay="0" title="Copied!">
|
|
|
|
<IconButton onClick= {()=> (navigator.clipboard.writeText(this.state.token) & this.setState({copied:true}))}>
|
2022-02-02 09:29:05 +00:00
|
|
|
<ContentCopy color={this.props.avatarLoaded & !this.state.copied & !this.state.bad_request ? 'primary' : 'inherit' } sx={{width:18, height:18}}/>
|
2022-02-01 22:05:49 +00:00
|
|
|
</IconButton>
|
|
|
|
</Tooltip>,
|
2022-01-30 15:18:03 +00:00
|
|
|
endAdornment:
|
2022-02-01 22:05:49 +00:00
|
|
|
<Tooltip enterTouchDelay="250" title="Generate a new token">
|
|
|
|
<IconButton onClick={this.handleClickNewRandomToken}><CasinoIcon/></IconButton>
|
|
|
|
</Tooltip>,
|
2022-01-30 15:18:03 +00:00
|
|
|
}}
|
2022-01-18 13:20:19 +00:00
|
|
|
/>
|
|
|
|
</Grid>
|
2022-01-03 14:27:25 +00:00
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="center">
|
2022-02-02 09:29:05 +00:00
|
|
|
{this.state.tokenHasChanged ?
|
|
|
|
<Button type="submit" size='small' onClick= {this.handleClickSubmitToken}>
|
|
|
|
<SmartToyIcon sx={{width:18, height:18}} />
|
|
|
|
<span> Generate Robot</span>
|
|
|
|
</Button>
|
|
|
|
:
|
2022-02-08 16:20:41 +00:00
|
|
|
<Tooltip enterTouchDelay="0" enterDelay="500" enterNextDelay="2000" title="You must enter a new token first">
|
2022-02-02 16:26:10 +00:00
|
|
|
<div>
|
2022-02-02 09:29:05 +00:00
|
|
|
<Button disabled={true} type="submit" size='small' >
|
2022-01-30 15:18:03 +00:00
|
|
|
<SmartToyIcon sx={{width:18, height:18}} />
|
|
|
|
<span> Generate Robot</span>
|
2022-01-30 13:18:32 +00:00
|
|
|
</Button>
|
2022-02-02 16:26:10 +00:00
|
|
|
</div>
|
|
|
|
</Tooltip>
|
2022-02-02 09:29:05 +00:00
|
|
|
}
|
2022-01-03 14:27:25 +00:00
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<ButtonGroup variant="contained" aria-label="outlined primary button group">
|
2022-01-30 13:18:32 +00:00
|
|
|
<Button disabled={this.state.loadingRobot} color='primary' to='/make/' component={Link}>Make Order</Button>
|
2022-01-15 00:28:19 +00:00
|
|
|
<Button color='inherit' onClick={this.handleClickOpenInfo}>Info</Button>
|
|
|
|
<this.InfoDialog/>
|
2022-01-30 20:24:14 +00:00
|
|
|
<Button disabled={this.state.loadingRobot} color='secondary' to='/book/' component={Link}>View Book</Button>
|
2022-01-03 14:27:25 +00:00
|
|
|
</ButtonGroup>
|
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<Typography component="h5" variant="h5">
|
2022-01-08 20:14:19 +00:00
|
|
|
Simple and Private Lightning peer-to-peer Exchange
|
2022-01-03 14:27:25 +00:00
|
|
|
</Typography>
|
2022-01-02 21:41:22 +00:00
|
|
|
</Grid>
|
|
|
|
</Grid>
|
2022-01-02 17:42:33 +00:00
|
|
|
);
|
|
|
|
}
|
2022-01-02 00:19:18 +00:00
|
|
|
}
|