Add UI, switch rewards, switch advanced, allow bondless, robologo

This commit is contained in:
Reckless_Satoshi 2022-03-15 11:20:57 -07:00
parent a172dff17b
commit a3b19d871f
No known key found for this signature in database
GPG Key ID: 9C4585B561315571
11 changed files with 391 additions and 217 deletions

View File

@ -18,4 +18,4 @@ class ChatRoomAdmin(AdminChangeLinksMixin, admin.ModelAdmin):
"room_group_name",
)
change_links = ["order","maker","taker"]
search_fields = ["id","maker__chat_maker"]
search_fields = ["id"]

View File

@ -15,4 +15,5 @@ RUN apk --no-cache --no-progress add shadow=~4 sudo=~1 gettext=~0.21 && \
USER root
COPY entrypoint.sh /root/entrypoint.sh
COPY lnd.conf /tmp/lnd.conf
ENTRYPOINT [ "/root/entrypoint.sh" ]

View File

@ -1,5 +1,5 @@
import React, { Component } from 'react'
import {Chip, CircularProgress, Badge, Tooltip, TextField, ListItemAvatar, Button, Avatar,Paper, Grid, IconButton, Typography, Select, MenuItem, List, ListItemText, ListItem, ListItemIcon, ListItemButton, Divider, Dialog, DialogContent} from "@mui/material";
import {FormControlLabel, Switch, CircularProgress, Badge, Tooltip, TextField, ListItemAvatar, Button, Avatar,Paper, Grid, IconButton, Typography, Select, MenuItem, List, ListItemText, ListItem, ListItemIcon, ListItemButton, Divider, Dialog, DialogContent} from "@mui/material";
import MediaQuery from 'react-responsive'
import { Link } from 'react-router-dom'
@ -74,6 +74,7 @@ export default class BottomBar extends Component {
profileShown: false,
alternative_site: 'robosats...',
node_id: '00000000',
showRewards: false,
referral_link: 'Loading...',
earned_rewards: 0,
rewardInvoice: null,
@ -343,80 +344,92 @@ export default class BottomBar extends Component {
</ListItemText>
</ListItem>
<Divider><Chip label='Rewards & Compensations'/></Divider>
<ListItem>
<ListItemIcon>
<PersonAddAltIcon/>
</ListItemIcon>
<ListItemText secondary="Share to earn 100 Sats per trade">
<TextField
label='Your Referral Link'
value={this.state.referral_link}
// variant='filled'
size='small'
InputProps={{
endAdornment:
<Tooltip disableHoverListener enterTouchDelay="0" title="Copied!">
<IconButton onClick= {()=>navigator.clipboard.writeText(this.state.referral_link)}>
<ContentCopy />
</IconButton>
</Tooltip>,
}}
/>
</ListItemText>
</ListItem>
<Divider/>
<ListItem>
<ListItemIcon>
<EmojiEventsIcon/>
</ListItemIcon>
{!this.state.openClaimRewards ?
<ListItemText secondary="Your earned rewards">
<Grid container xs={12}>
<Grid item xs={9}>
<Typography>{this.state.earned_rewards+" Sats"}</Typography>
</Grid>
<Grid item xs={3}>
<Button disabled={this.state.earned_rewards==0? true : false} onClick={() => this.setState({openClaimRewards:true})} variant="contained" size="small">Claim</Button>
</Grid>
</Grid>
</ListItemText>
:
<form style={{maxWidth: 270}}>
<Grid alignItems="stretch" style={{ display: "flex"}} align="center">
<Grid item alignItems="stretch" style={{ display: "flex" }} align="center">
<TextField
error={this.state.badInvoice}
helperText={this.state.badInvoice ? this.state.badInvoice : "" }
label={"Invoice for " + this.state.earned_rewards + " Sats"}
//variant="standard"
size="small"
value={this.state.rewardInvoice}
onChange={e => {
this.setState({ rewardInvoice: e.target.value });
<Grid spacing={1} align="center">
<FormControlLabel labelPlacement="start"control={
<Switch
checked={this.state.showRewards}
onChange={()=> this.setState({showRewards: !this.state.showRewards})}/>}
label="Rewards and compensations"
/>
</Grid>
<div style={{ display: this.state.showRewards ? '':'none'}}>
<ListItem>
<ListItemIcon>
<PersonAddAltIcon/>
</ListItemIcon>
<ListItemText secondary="Share to earn 100 Sats per trade">
<TextField
label='Your referral link'
value={this.state.referral_link}
// variant='filled'
size='small'
InputProps={{
endAdornment:
<Tooltip disableHoverListener enterTouchDelay="0" title="Copied!">
<IconButton onClick= {()=>navigator.clipboard.writeText(this.state.referral_link)}>
<ContentCopy />
</IconButton>
</Tooltip>,
}}
/>
</ListItemText>
</ListItem>
<ListItem>
<ListItemIcon>
<EmojiEventsIcon/>
</ListItemIcon>
{!this.state.openClaimRewards ?
<ListItemText secondary="Your earned rewards">
<Grid container xs={12}>
<Grid item xs={9}>
<Typography>{this.state.earned_rewards+" Sats"}</Typography>
</Grid>
<Grid item xs={3}>
<Button disabled={this.state.earned_rewards==0? true : false} onClick={() => this.setState({openClaimRewards:true})} variant="contained" size="small">Claim</Button>
</Grid>
</Grid>
<Grid item alignItems="stretch" style={{ display: "flex" }}>
<Button sx={{maxHeight:38}} onClick={this.handleSubmitInvoiceClicked} variant="contained" color="primary" size="small" > Submit </Button>
</ListItemText>
:
<form style={{maxWidth: 270}}>
<Grid alignItems="stretch" style={{ display: "flex"}} align="center">
<Grid item alignItems="stretch" style={{ display: "flex" }} align="center">
<TextField
error={this.state.badInvoice}
helperText={this.state.badInvoice ? this.state.badInvoice : "" }
label={"Invoice for " + this.state.earned_rewards + " Sats"}
//variant="standard"
size="small"
value={this.state.rewardInvoice}
onChange={e => {
this.setState({ rewardInvoice: e.target.value });
}}
/>
</Grid>
<Grid item alignItems="stretch" style={{ display: "flex" }}>
<Button sx={{maxHeight:38}} onClick={this.handleSubmitInvoiceClicked} variant="contained" color="primary" size="small" > Submit </Button>
</Grid>
</Grid>
</Grid>
</form>
}
</ListItem>
</form>
}
</ListItem>
{this.state.showRewardsSpinner?
<div style={{display: 'flex', justifyContent: 'center'}}>
<CircularProgress/>
</div>
:""}
{this.state.withdrawn?
<div style={{display: 'flex', justifyContent: 'center'}}>
<Typography color="primary" variant="body2"><b>There it goes, thank you!🥇</b></Typography>
</div>
:""}
{this.state.showRewardsSpinner?
<div style={{display: 'flex', justifyContent: 'center'}}>
<CircularProgress/>
</div>
:""}
{this.state.withdrawn?
<div style={{display: 'flex', justifyContent: 'center'}}>
<Typography color="primary" variant="body2"><b>There it goes, thank you!🥇</b></Typography>
</div>
:""}
</List>
</DialogContent>

View File

@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { Tooltip, Paper, Button , Grid, Typography, TextField, Select, FormHelperText, MenuItem, FormControl, Radio, FormControlLabel, RadioGroup} from "@mui/material"
import { Checkbox, Switch, Tooltip, Paper, Button , Grid, Typography, TextField, Select, FormHelperText, MenuItem, FormControl, Radio, FormControlLabel, RadioGroup} from "@mui/material"
import { Link } from 'react-router-dom'
import getFlags from './getFlags'
@ -48,7 +48,9 @@ export default class MakerPage extends Component {
payment_method: this.defaultPaymentMethod,
premium: 0,
satoshis: null,
currencies_dict: {"1":"USD"}
currencies_dict: {"1":"USD"},
showAdvanced: false,
allowBondless: false,
}
this.getCurrencyDict()
}
@ -152,7 +154,174 @@ export default class MakerPage extends Component {
return this.state.currencies_dict[val.toString()]
}
StandardMakerOptions = () => {
return(
<Paper elevation={12} style={{ padding: 8, width:240, align:'center'}}>
<Grid item xs={12} align="center" spacing={1}>
<FormControl component="fieldset">
<FormHelperText>
Buy or Sell Bitcoin?
</FormHelperText>
<RadioGroup row defaultValue="0" onChange={this.handleTypeChange}>
<FormControlLabel
value="0"
control={<Radio color="primary"/>}
label="Buy"
labelPlacement="Top"
/>
<FormControlLabel
value="1"
control={<Radio color="secondary"/>}
label="Sell"
labelPlacement="Top"
/>
</RadioGroup>
</FormControl>
</Grid>
<Grid containter xs={12} alignItems="stretch" style={{ display: "flex" }}>
<div style={{maxWidth:140}}>
<Tooltip placement="top" enterTouchDelay="500" enterDelay="700" enterNextDelay="2000" title="Amount of fiat to exchange for bitcoin">
<TextField
error={this.state.amount <= 0}
helperText={this.state.amount <= 0 ? 'Invalid' : null}
label="Amount"
type="number"
required="true"
inputProps={{
min:0 ,
style: {textAlign:"center"}
}}
onChange={this.handleAmountChange}
/>
</Tooltip>
</div>
<div >
<Select
required="true"
defaultValue={this.defaultCurrency}
inputProps={{
style: {textAlign:"center"}
}}
onChange={this.handleCurrencyChange}>
{Object.entries(this.state.currencies_dict)
.map( ([key, value]) => <MenuItem value={parseInt(key)}>
<div style={{display:'flex',alignItems:'center', flexWrap:'wrap'}}>{getFlags(value)}{" "+value}</div>
</MenuItem> )}
</Select>
</div>
</Grid>
<br/>
<Grid item xs={12} align="center">
<Tooltip placement="top" enterTouchDelay="300" enterDelay="700" enterNextDelay="2000" title="Enter your preferred fiat payment methods. Instant recommended (e.g., Revolut, CashApp ...)">
<TextField
sx={{width:240}}
label={this.state.currency==1000 ? "Swap Destination (e.g. rBTC)":"Fiat Payment Method(s)"}
error={this.state.badPaymentMethod}
helperText={this.state.badPaymentMethod ? "Must be shorter than 35 characters":""}
type="text"
require={true}
inputProps={{
style: {textAlign:"center"},
maxLength: 35
}}
onChange={this.handlePaymentMethodChange}
/>
</Tooltip>
</Grid>
<Grid item xs={12} align="center">
<FormControl component="fieldset">
<FormHelperText >
<div align='center'>
Choose a Pricing Method
</div>
</FormHelperText>
<RadioGroup row defaultValue="relative">
<Tooltip placement="top" enterTouchDelay="0" enterDelay="1000" enterNextDelay="2000" title="Let the price move with the market">
<FormControlLabel
value="relative"
control={<Radio color="primary"/>}
label="Relative"
labelPlacement="Top"
onClick={this.handleClickRelative}
/>
</Tooltip>
<Tooltip placement="top" enterTouchDelay="0" enterDelay="1000" enterNextDelay="2000" title="Set a fix amount of satoshis">
<FormControlLabel
value="explicit"
control={<Radio color="secondary"/>}
label="Explicit"
labelPlacement="Top"
onClick={this.handleClickExplicit}
/>
</Tooltip>
</RadioGroup>
</FormControl>
</Grid>
{/* conditional shows either Premium % field or Satoshis field based on pricing method */}
<Grid item xs={12} align="center">
<div style={{display: this.state.is_explicit ? '':'none'}}>
<TextField
sx={{width:240}}
label="Satoshis"
error={this.state.badSatoshis}
helperText={this.state.badSatoshis}
type="number"
required="true"
value={this.state.satoshis}
inputProps={{
// TODO read these from .env file
min:this.minTradeSats ,
max:this.maxTradeSats ,
style: {textAlign:"center"}
}}
onChange={this.handleSatoshisChange}
// defaultValue={this.defaultSatoshis}
/>
</div>
<div style={{display: this.state.is_explicit ? 'none':''}}>
<TextField
sx={{width:240}}
error={this.state.badPremium}
helperText={this.state.badPremium}
label="Premium over Market (%)"
type="number"
// defaultValue={this.defaultPremium}
inputProps={{
min: -100,
max: 999,
style: {textAlign:"center"}
}}
onChange={this.handlePremiumChange}
/>
</div>
</Grid>
</Paper>
)
}
AdvancedMakerOptions = () => {
return(
<Paper elevation={12} style={{ padding: 8, width:300, align:'center'}}>
<Grid item xs={12} align="center" spacing={1}>
<Tooltip enterTouchDelay="0" title="Takers will not have to lock a bond. High risk! Only small stakes allowed!">
<FormControlLabel
label={<a>Allow bondless taker (<a href="https://git.robosats.com" target="_blank">Read More</a>)</a>}
control={
<Checkbox
disabled={this.state.type==0}
color="secondary"
checked={this.state.allowBondless}
onChange={()=> this.setState({allowBondless: !this.state.allowBondless})}
/>
}
/>
</Tooltip>
</Grid>
</Paper>
)
}
render() {
return (
<Grid container xs={12} align="center" spacing={1} sx={{minWidth:380}}>
@ -161,150 +330,30 @@ export default class MakerPage extends Component {
ORDER MAKER
</Typography>
</Grid> */}
<Grid item xs={12} align="center" spacing={1}>
<Paper elevation={12} style={{ padding: 8, width:240, align:'center'}}>
<Grid item xs={12} align="center" spacing={1}>
<FormControl component="fieldset">
<FormHelperText>
Buy or Sell Bitcoin?
</FormHelperText>
<RadioGroup row defaultValue="0" onChange={this.handleTypeChange}>
<FormControlLabel
value="0"
control={<Radio color="primary"/>}
label="Buy"
labelPlacement="Top"
/>
<FormControlLabel
value="1"
control={<Radio color="secondary"/>}
label="Sell"
labelPlacement="Top"
/>
</RadioGroup>
</FormControl>
</Grid>
<Grid containter xs={12} alignItems="stretch" style={{ display: "flex" }}>
<div style={{maxWidth:140}}>
<Tooltip placement="top" enterTouchDelay="500" enterDelay="700" enterNextDelay="2000" title="Amount of fiat to exchange for bitcoin">
<TextField
error={this.state.amount <= 0}
helperText={this.state.amount <= 0 ? 'Invalid' : null}
label="Amount"
type="number"
required="true"
inputProps={{
min:0 ,
style: {textAlign:"center"}
}}
onChange={this.handleAmountChange}
/>
</Tooltip>
</div>
<div >
<Select
required="true"
defaultValue={this.defaultCurrency}
inputProps={{
style: {textAlign:"center"}
}}
onChange={this.handleCurrencyChange}>
{Object.entries(this.state.currencies_dict)
.map( ([key, value]) => <MenuItem value={parseInt(key)}>
<div style={{display:'flex',alignItems:'center', flexWrap:'wrap'}}>{getFlags(value)}{" "+value}</div>
</MenuItem> )}
</Select>
</div>
</Grid>
<br/>
<Grid item xs={12} align="center">
<Tooltip placement="top" enterTouchDelay="300" enterDelay="700" enterNextDelay="2000" title="Enter your prefered fiat payment methods (instant recommended)">
<TextField
sx={{width:240}}
label={this.state.currency==1000 ? "Swap Destination (e.g. rBTC)":"Fiat Payment Method(s)"}
error={this.state.badPaymentMethod}
helperText={this.state.badPaymentMethod ? "Must be shorter than 35 characters":""}
type="text"
require={true}
inputProps={{
style: {textAlign:"center"},
maxLength: 35
}}
onChange={this.handlePaymentMethodChange}
<div className="advancedSwitch">
<Tooltip enterTouchDelay="0" title="Comming soon">
<FormControlLabel
labelPlacement="start"control={
<Switch
//disabled
checked={this.state.showAdvanced}
onChange={()=> this.setState({showAdvanced: !this.state.showAdvanced})}/>}
label="Advanced"
/>
</Tooltip>
</div>
</Grid>
<Grid item xs={12} align="center">
<FormControl component="fieldset">
<FormHelperText >
<div align='center'>
Choose a Pricing Method
</div>
</FormHelperText>
<RadioGroup row defaultValue="relative">
<Tooltip placement="top" enterTouchDelay="0" enterDelay="1000" enterNextDelay="2000" title="Let the price move with the market">
<FormControlLabel
value="relative"
control={<Radio color="primary"/>}
label="Relative"
labelPlacement="Top"
onClick={this.handleClickRelative}
/>
</Tooltip>
<Tooltip placement="top" enterTouchDelay="0" enterDelay="1000" enterNextDelay="2000" title="Set a fix amount of satoshis">
<FormControlLabel
value="explicit"
control={<Radio color="secondary"/>}
label="Explicit"
labelPlacement="Top"
onClick={this.handleClickExplicit}
/>
</Tooltip>
</RadioGroup>
</FormControl>
</Grid>
{/* conditional shows either Premium % field or Satoshis field based on pricing method */}
<Grid item xs={12} align="center">
<div style={{display: this.state.is_explicit ? '':'none'}}>
<TextField
sx={{width:240}}
label="Satoshis"
error={this.state.badSatoshis}
helperText={this.state.badSatoshis}
type="number"
required="true"
value={this.state.satoshis}
inputProps={{
// TODO read these from .env file
min:this.minTradeSats ,
max:this.maxTradeSats ,
style: {textAlign:"center"}
}}
onChange={this.handleSatoshisChange}
// defaultValue={this.defaultSatoshis}
/>
</div>
<div style={{display: this.state.is_explicit ? 'none':''}}>
<TextField
sx={{width:240}}
error={this.state.badPremium}
helperText={this.state.badPremium}
label="Premium over Market (%)"
type="number"
// defaultValue={this.defaultPremium}
inputProps={{
min: -100,
max: 999,
style: {textAlign:"center"}
}}
onChange={this.handlePremiumChange}
/>
</div>
</Grid>
</Paper>
<Grid item xs={12} align="center" spacing={1}>
<div style={{ display: this.state.showAdvanced == false ? '':'none'}}>
<this.StandardMakerOptions/>
</div>
<div style={{ display: this.state.showAdvanced == true ? '':'none'}}>
<this.AdvancedMakerOptions/>
</div>
</Grid>
<Grid item xs={12} align="center">
{/* conditions to disable the make button */}
{(this.state.amount == null ||

View File

@ -385,7 +385,7 @@ export default class TradeBox extends Component {
<Typography component="body2" variant="body2" align="left">
<p>Be patient while robots check the book.
It might take some time. This box will ring 🔊 once a robot takes your order. </p>
<p>Please note that if your premium is excessive, or your currency or payment
<p>Please note that if your premium is excessive or your currency or payment
methods are not popular, your order might expire untaken. Your bond will
return to you (no action needed).</p>
</Typography>
@ -970,7 +970,7 @@ handleRatingRobosatsChange=(e)=>{
<Grid item xs={12} align="center">
<Typography component="body2" variant="body2" align="center">
Your invoice has expired or more than 3 payment attempts have been made.
Muun is not recommended, <a href="https://github.com/Reckless-Satoshi/robosats/issues/44">check the list of
Muun wallet is not recommended, <a href="https://github.com/Reckless-Satoshi/robosats/issues/44">check the list of
compatible wallets</a>
</Typography>
</Grid>
@ -1011,7 +1011,7 @@ handleRatingRobosatsChange=(e)=>{
<Grid item xs={12} align="center">
<Typography component="body2" variant="body2" align="center">
RoboSats will try to pay your invoice 3 times every 5 minutes. If it keeps failing, you
will be able to submit a new invoice. Check whether you have enough inboud liquidity.
will be able to submit a new invoice. Check whether you have enough inbound liquidity.
Remember that lightning nodes must be online in order to receive payments.
</Typography>
<List>

View File

@ -6,6 +6,7 @@ import InfoDialog from './InfoDialog'
import SmartToyIcon from '@mui/icons-material/SmartToy';
import CasinoIcon from '@mui/icons-material/Casino';
import ContentCopy from "@mui/icons-material/ContentCopy";
import RoboSatsIcon from "./icons/RoboSatsIcon"
function getCookie(name) {
let cookieValue = null;
@ -149,6 +150,9 @@ export default class UserGenPage extends Component {
render() {
return (
<Grid container spacing={1}>
<Grid item>
<div style={{height:40}}/>
</Grid>
<Grid item xs={12} align="center" sx={{width:370, height:260}}>
{!this.state.loadingRobot ?
<div>
@ -243,11 +247,26 @@ export default class UserGenPage extends Component {
<Button disabled={this.state.loadingRobot} color='secondary' to='/book/' component={Link}>View Book</Button>
</ButtonGroup>
</Grid>
<Grid item xs={12} align="center">
<Typography component="h5" variant="h5">
Simple and Private Lightning peer-to-peer Exchange
</Typography>
<Grid item xs={12} align="center" spacing={2} sx={{width:370}}>
<Grid item>
<div style={{height:30}}/>
</Grid>
<div style={{width:370, left:30}}>
<Grid container xs={12} align="center">
<Grid item xs={0.8}/>
<Grid item xs={7.5} align="right">
<Typography component="h5" variant="h5">
Simple and Private LN P2P Exchange
</Typography>
</Grid>
<Grid item xs={2.5} align="left">
<RoboSatsIcon color="primary" sx={{height:70, width:70}}/>
</Grid>
</Grid>
</div>
</Grid>
</Grid>
);
}

View File

@ -0,0 +1,81 @@
import React, { Component } from "react";
import { SvgIcon } from "@mui/material"
export default function RoboSatsIcon(props) {
return (
<SvgIcon {...props} x="0px" y="0px" width="1000px" height="1000px" viewBox="0 0 1000 900">
<g>
<path d="M602.336,731.51c16.747-16.94,29.249-35.524,37.504-56.694c18.792-48.193,16.967-94.996-10.46-139.81
c-10.255-16.756-24.983-29.293-39.461-42.103c-67.731-59.932-135.412-119.919-203.104-179.895
c-0.368-0.326-0.644-0.755-1.331-1.579c18.529-12.477,36.983-24.903,55.872-37.62c-9.61-6.799-18.917-13.385-28.648-20.27
c11.763-14.483,23.273-28.656,34.738-42.773c13.313,7.081,24.784,5.523,32.075-4.132c6.395-8.467,5.794-20.59-1.412-28.52
c-7.011-7.713-19.494-9.295-28.343-3.592c-10.274,6.623-12.651,17.652-6.576,31.65c-22.681,16.451-45.436,32.955-68.921,49.989
c9.33,6.786,18.246,13.271,27.611,20.084c-9.232,8.573-18.09,16.797-27.064,25.131c-68.348-47.917-134.895-38.158-199.771,10.745
c0-100.562,0-201.3,0-302.535c1.811-0.082,3.562-0.23,5.313-0.23c97.991-0.011,195.983-0.214,293.973,0.094
c37.661,0.119,75.351,1.898,112.093,11.01c52.81,13.096,95.741,40.904,125.379,87.462c13.802,21.681,20.643,45.764,23.136,71.039
c3.595,36.436,1.313,72.517-8.858,107.873c-11.943,41.515-37.09,74.011-69.641,101.357c-16.133,13.552-33.803,24.811-52.581,34.343
c-1.3,0.659-2.533,1.445-4.148,2.375c80.735,102.152,161.255,204.034,242.318,306.6C761.843,731.51,682.637,731.51,602.336,731.51z
"/>
<path d="M282.877,389.186c25.706-0.109,46.42,20.376,46.55,46.038c0.131,25.994-20.404,46.852-46.238,46.96
c-25.588,0.108-46.928-21.172-46.758-46.627C236.602,409.95,257.291,389.295,282.877,389.186z"/>
<path d="M445.93,607.736c0.705-26.031,21.515-46.381,46.915-45.881c26.295,0.52,46.657,21.756,45.918,47.887
c-0.721,25.455-21.862,45.67-47.178,45.104C465.779,654.273,445.244,633.082,445.93,607.736z"/>
<path d="M175.223,550.758c23.365,20.689,46.15,40.865,69.337,61.396c-4.974,5.619-9.792,11.063-14.91,16.846
c-5.634-4.988-11.167-9.738-16.519-14.684c-3.131-2.896-5.343-2.492-8.415,0.467c-9.944,9.58-20.234,18.801-29.493,27.332
C175.223,613.414,175.223,582.512,175.223,550.758z"/>
<path d="M379.124,731.533c-30.045,0-59.057,0-89.151,0c8.955-9.23,17.236-17.769,25.724-26.519
c-6.368-5.709-12.409-11.127-18.739-16.803c4.904-5.559,9.594-10.877,14.65-16.608C334.013,691.492,356.2,711.186,379.124,731.533z
"/>
</g>
<g>
<path d="M208.875,819.362h-15.495v34.557h-19.45v-94.397h35.075c11.151,0,19.752,2.485,25.804,7.455
c6.051,4.972,9.077,11.995,9.077,21.071c0,6.44-1.394,11.811-4.182,16.111s-7.013,7.727-12.675,10.276l20.422,38.576v0.907h-20.876
L208.875,819.362z M193.379,803.608h15.69c4.884,0,8.666-1.242,11.346-3.729c2.68-2.484,4.02-5.91,4.02-10.276
c0-4.451-1.264-7.952-3.792-10.503c-2.529-2.55-6.409-3.825-11.638-3.825h-15.625V803.608z"/>
<path d="M336.208,808.859c0,9.294-1.643,17.44-4.927,24.442c-3.285,7.002-7.985,12.405-14.101,16.209
c-6.117,3.804-13.129,5.705-21.039,5.705c-7.824,0-14.805-1.881-20.941-5.641c-6.138-3.761-10.892-9.131-14.263-16.111
c-3.372-6.979-5.08-15.009-5.122-24.086v-4.668c0-9.292,1.674-17.473,5.024-24.539c3.349-7.067,8.082-12.491,14.199-16.273
c6.116-3.781,13.106-5.673,20.974-5.673c7.866,0,14.857,1.892,20.974,5.673c6.116,3.782,10.849,9.206,14.199,16.273
c3.349,7.066,5.024,15.226,5.024,24.475V808.859z M316.499,804.58c0-9.896-1.773-17.418-5.316-22.562
c-3.545-5.144-8.602-7.716-15.171-7.716c-6.527,0-11.563,2.54-15.106,7.618c-3.545,5.079-5.339,12.524-5.381,22.335v4.604
c0,9.639,1.772,17.116,5.316,22.433c3.543,5.316,8.644,7.975,15.301,7.975c6.526,0,11.541-2.561,15.042-7.683
s5.272-12.588,5.316-22.4V804.58z"/>
<path d="M350.342,853.919v-94.397h33.065c11.453,0,20.141,2.193,26.063,6.58c5.921,4.388,8.882,10.817,8.882,19.288
c0,4.626-1.189,8.699-3.566,12.222c-2.377,3.522-5.684,6.105-9.919,7.747c4.84,1.211,8.655,3.653,11.443,7.326
c2.788,3.675,4.182,8.169,4.182,13.485c0,9.077-2.896,15.949-8.688,20.617c-5.792,4.668-14.047,7.046-24.767,7.132H350.342z
M369.792,799.069h14.393c9.811-0.172,14.717-4.084,14.717-11.734c0-4.279-1.243-7.358-3.728-9.239
c-2.486-1.88-6.408-2.82-11.767-2.82h-13.615V799.069z M369.792,812.814v25.479h16.662c4.581,0,8.158-1.091,10.73-3.274
c2.571-2.182,3.858-5.196,3.858-9.044c0-8.645-4.474-13.031-13.421-13.161H369.792z"/>
<path d="M512.621,808.859c0,9.294-1.645,17.44-4.928,24.442c-3.285,7.002-7.986,12.405-14.102,16.209
c-6.117,3.804-13.129,5.705-21.039,5.705c-7.824,0-14.805-1.881-20.941-5.641c-6.138-3.761-10.892-9.131-14.263-16.111
c-3.372-6.979-5.08-15.009-5.122-24.086v-4.668c0-9.292,1.674-17.473,5.024-24.539c3.349-7.067,8.082-12.491,14.199-16.273
c6.116-3.781,13.106-5.673,20.974-5.673c7.866,0,14.857,1.892,20.974,5.673c6.116,3.782,10.849,9.206,14.199,16.273
c3.35,7.066,5.025,15.226,5.025,24.475V808.859z M492.911,804.58c0-9.896-1.773-17.418-5.316-22.562
c-3.545-5.144-8.602-7.716-15.171-7.716c-6.527,0-11.563,2.54-15.106,7.618c-3.545,5.079-5.339,12.524-5.381,22.335v4.604
c0,9.639,1.772,17.116,5.316,22.433c3.543,5.316,8.644,7.975,15.301,7.975c6.526,0,11.541-2.561,15.042-7.683
s5.272-12.588,5.316-22.4V804.58z"/>
<path d="M575.704,829.152c0-3.673-1.297-6.493-3.891-8.461c-2.593-1.966-7.261-4.041-14.004-6.224
c-6.742-2.183-12.081-4.333-16.014-6.451c-10.72-5.791-16.079-13.593-16.079-23.405c0-5.1,1.437-9.648,4.312-13.647
c2.874-3.997,7.002-7.12,12.384-9.368c5.381-2.247,11.421-3.371,18.121-3.371c6.742,0,12.75,1.222,18.023,3.663
c5.272,2.442,9.368,5.89,12.286,10.341c2.917,4.452,4.376,9.509,4.376,15.171h-19.45c0-4.321-1.361-7.683-4.084-10.081
c-2.724-2.399-6.549-3.599-11.476-3.599c-4.756,0-8.451,1.005-11.087,3.015c-2.637,2.01-3.955,4.658-3.955,7.942
c0,3.069,1.545,5.641,4.636,7.715c3.09,2.075,7.64,4.02,13.647,5.835c11.064,3.329,19.126,7.456,24.184,12.384
c5.057,4.927,7.585,11.065,7.585,18.412c0,8.169-3.091,14.578-9.271,19.224c-6.181,4.646-14.501,6.97-24.961,6.97
c-7.261,0-13.874-1.329-19.839-3.987s-10.514-6.299-13.647-10.925c-3.134-4.624-4.7-9.984-4.7-16.078h19.515
c0,10.416,6.225,15.624,18.672,15.624c4.625,0,8.234-0.939,10.827-2.82C574.407,835.149,575.704,832.523,575.704,829.152z"/>
<path d="M661.673,834.469H627.57l-6.483,19.45h-20.682l35.14-94.397h18.023l35.335,94.397h-20.683L661.673,834.469z
M632.822,818.714h23.599l-11.864-35.334L632.822,818.714z"/>
<path d="M760.999,775.275h-28.916v78.644h-19.45v-78.644h-28.526v-15.754h76.893V775.275z"/>
<path d="M819.997,829.152c0-3.673-1.297-6.493-3.891-8.461c-2.593-1.966-7.261-4.041-14.004-6.224
c-6.742-2.183-12.081-4.333-16.014-6.451c-10.72-5.791-16.079-13.593-16.079-23.405c0-5.1,1.437-9.648,4.312-13.647
c2.874-3.997,7.002-7.12,12.384-9.368c5.381-2.247,11.421-3.371,18.121-3.371c6.742,0,12.75,1.222,18.023,3.663
c5.272,2.442,9.368,5.89,12.286,10.341c2.917,4.452,4.376,9.509,4.376,15.171h-19.45c0-4.321-1.361-7.683-4.084-10.081
c-2.724-2.399-6.549-3.599-11.476-3.599c-4.756,0-8.451,1.005-11.087,3.015c-2.637,2.01-3.955,4.658-3.955,7.942
c0,3.069,1.545,5.641,4.636,7.715c3.09,2.075,7.64,4.02,13.647,5.835c11.064,3.329,19.126,7.456,24.184,12.384
c5.057,4.927,7.585,11.065,7.585,18.412c0,8.169-3.091,14.578-9.271,19.224c-6.181,4.646-14.501,6.97-24.961,6.97
c-7.261,0-13.874-1.329-19.839-3.987s-10.514-6.299-13.647-10.925c-3.134-4.624-4.7-9.984-4.7-16.078h19.515
c0,10.416,6.225,15.624,18.672,15.624c4.625,0,8.234-0.939,10.827-2.82C818.7,835.149,819.997,832.523,819.997,829.152z"/>
</g>
</SvgIcon>
);
}

View File

@ -32,6 +32,13 @@ body {
height: 40px;
}
.advancedSwitch{
width: 240;
left: 50%;
transform: translate(55px, 0px);
margin-right: 0;
margin-left: auto;
}
.bottomItem {
margin: 0;
top: -14px;

File diff suppressed because one or more lines are too long

View File

@ -162,6 +162,10 @@
!*** ./node_modules/stylis/src/Tokenizer.js ***!
\**********************************************/
/*!**********************************************!*\
!*** ./src/components/icons/RoboSatsIcon.js ***!
\**********************************************/
/*!***********************************************!*\
!*** ./node_modules/@mui/base/NoSsr/NoSsr.js ***!
\***********************************************/

View File

@ -39,7 +39,7 @@ app.conf.beat_schedule = {
"task": "give_rewards",
"schedule": crontab(hour=0, minute=0),
},
"cache-market-prices": { # Cache market prices every minutes for now.
"cache-market-prices": { # Cache market prices every minute
"task": "cache_external_market_prices",
"schedule": timedelta(seconds=60),
},