mirror of
https://github.com/RoboSats/robosats.git
synced 2025-02-21 12:49:02 +00:00
Run linter and add linter GH action
This commit is contained in:
parent
9d73f1ec34
commit
14487a9c2d
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@ -16,7 +16,7 @@ on:
|
|||||||
branches: [ "main" ]
|
branches: [ "main" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
# The branches below must be a subset of the branches above
|
# The branches below must be a subset of the branches above
|
||||||
branches: [ "main" ]
|
# branches: [ "main" ]
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '39 10 * * 2'
|
- cron: '39 10 * * 2'
|
||||||
|
|
||||||
|
39
.github/workflows/linter.yml
vendored
Normal file
39
.github/workflows/linter.yml
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
name: Lint
|
||||||
|
|
||||||
|
on:
|
||||||
|
# Trigger the workflow on push or pull request,
|
||||||
|
# but only for the main branch
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
run-linters:
|
||||||
|
name: Run linters
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Check out Git repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: 'Setup node'
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 16.17.0
|
||||||
|
cache: npm
|
||||||
|
cache-dependency-path: frontend/package-lock.json
|
||||||
|
|
||||||
|
# ESLint and Prettier must be in `package.json`
|
||||||
|
- name: 'Install NPM Dependencies'
|
||||||
|
run: |
|
||||||
|
cd frontend
|
||||||
|
npm install -f
|
||||||
|
|
||||||
|
- name: Run linters
|
||||||
|
uses: wearerequired/lint-action@v2
|
||||||
|
with:
|
||||||
|
prettier: true
|
||||||
|
prettier_dir: frontend
|
@ -1,13 +1,13 @@
|
|||||||
import React, { Component , Suspense } from "react";
|
import React, { Component, Suspense } from 'react';
|
||||||
import ReactDOM from 'react-dom/client';
|
import ReactDOM from 'react-dom/client';
|
||||||
import HomePage from "./HomePage";
|
import HomePage from './HomePage';
|
||||||
import { CssBaseline, IconButton , Link} from "@mui/material";
|
import { CssBaseline, IconButton, Link } from '@mui/material';
|
||||||
import { ThemeProvider, createTheme } from '@mui/material/styles';
|
import { ThemeProvider, createTheme } from '@mui/material/styles';
|
||||||
import UnsafeAlert from "./UnsafeAlert";
|
import UnsafeAlert from './UnsafeAlert';
|
||||||
import { LearnDialog } from "./Dialogs";
|
import { LearnDialog } from './Dialogs';
|
||||||
|
|
||||||
import { I18nextProvider } from "react-i18next";
|
import { I18nextProvider } from 'react-i18next';
|
||||||
import i18n from "./i18n";
|
import i18n from './i18n';
|
||||||
|
|
||||||
//Icons
|
//Icons
|
||||||
import DarkModeIcon from '@mui/icons-material/DarkMode';
|
import DarkModeIcon from '@mui/icons-material/DarkMode';
|
||||||
@ -24,63 +24,77 @@ export default class App extends Component {
|
|||||||
dark: window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches,
|
dark: window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches,
|
||||||
expandedSettings: false,
|
expandedSettings: false,
|
||||||
openLearn: false,
|
openLearn: false,
|
||||||
theme: {typography: { fontSize: 14 }},
|
theme: { typography: { fontSize: 14 } },
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
lightTheme = createTheme ({});
|
lightTheme = createTheme({});
|
||||||
|
|
||||||
darkTheme = createTheme({
|
darkTheme = createTheme({
|
||||||
palette: {
|
palette: {
|
||||||
mode: 'dark',
|
mode: 'dark',
|
||||||
background: {
|
background: {
|
||||||
default: "#070707"
|
default: '#070707',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
onSettingsClick = () => {
|
onSettingsClick = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
expandedSettings: ! this.state.expandedSettings
|
expandedSettings: !this.state.expandedSettings,
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
onZoomClick = (direction) => {
|
onZoomClick = (direction) => {
|
||||||
let zoomChange;
|
let zoomChange;
|
||||||
direction === "out" ? zoomChange = -1 : zoomChange = 1;
|
direction === 'out' ? (zoomChange = -1) : (zoomChange = 1);
|
||||||
this.setState(({theme}) => ({
|
this.setState(({ theme }) => ({
|
||||||
theme: {
|
theme: {
|
||||||
...theme,
|
...theme,
|
||||||
typography: {
|
typography: {
|
||||||
fontSize: this.state.theme.typography.fontSize + zoomChange,
|
fontSize: this.state.theme.typography.fontSize + zoomChange,
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
}));
|
}));
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Suspense fallback="loading language">
|
<Suspense fallback='loading language'>
|
||||||
<I18nextProvider i18n={i18n}>
|
<I18nextProvider i18n={i18n}>
|
||||||
<ThemeProvider theme={this.state.dark ? this.darkTheme : createTheme(this.state.theme)}>
|
<ThemeProvider theme={this.state.dark ? this.darkTheme : createTheme(this.state.theme)}>
|
||||||
<CssBaseline/>
|
<CssBaseline />
|
||||||
<LearnDialog open={this.state.openLearn} onClose={()=> this.setState({openLearn:false})}/>
|
<LearnDialog
|
||||||
<IconButton sx={{position:'fixed',right:'34px'}} onClick={()=> this.setState({openLearn:true})}><SchoolIcon/></IconButton>
|
open={this.state.openLearn}
|
||||||
<IconButton sx={{position:'fixed',right:'0px'}} onClick={()=>this.setState({dark:!this.state.dark})}>
|
onClose={() => this.setState({ openLearn: false })}
|
||||||
{this.state.dark ? <LightModeIcon/>:<DarkModeIcon/>}
|
/>
|
||||||
</IconButton>
|
<IconButton
|
||||||
<IconButton sx={{position:'fixed',right:'34px'}} onClick={()=> this.setState({openLearn:true})}><SchoolIcon/></IconButton>
|
sx={{ position: 'fixed', right: '34px' }}
|
||||||
<UnsafeAlert className="unsafeAlert"/>
|
onClick={() => this.setState({ openLearn: true })}
|
||||||
<HomePage {...this.state}/>
|
>
|
||||||
</ThemeProvider>
|
<SchoolIcon />
|
||||||
</I18nextProvider>
|
</IconButton>
|
||||||
|
<IconButton
|
||||||
|
sx={{ position: 'fixed', right: '0px' }}
|
||||||
|
onClick={() => this.setState({ dark: !this.state.dark })}
|
||||||
|
>
|
||||||
|
{this.state.dark ? <LightModeIcon /> : <DarkModeIcon />}
|
||||||
|
</IconButton>
|
||||||
|
<IconButton
|
||||||
|
sx={{ position: 'fixed', right: '34px' }}
|
||||||
|
onClick={() => this.setState({ openLearn: true })}
|
||||||
|
>
|
||||||
|
<SchoolIcon />
|
||||||
|
</IconButton>
|
||||||
|
<UnsafeAlert className='unsafeAlert' />
|
||||||
|
<HomePage {...this.state} />
|
||||||
|
</ThemeProvider>
|
||||||
|
</I18nextProvider>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const root = ReactDOM.createRoot(
|
const root = ReactDOM.createRoot(document.getElementById('app'));
|
||||||
document.getElementById("app")
|
|
||||||
);
|
|
||||||
|
|
||||||
root.render(<App />);
|
root.render(<App />);
|
||||||
|
@ -1,30 +1,30 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useAutocomplete } from '@mui/base/AutocompleteUnstyled';
|
import { useAutocomplete } from '@mui/base/AutocompleteUnstyled';
|
||||||
import { styled } from '@mui/material/styles';
|
import { styled } from '@mui/material/styles';
|
||||||
import { Button, Tooltip } from "@mui/material";
|
import { Button, Tooltip } from '@mui/material';
|
||||||
import { paymentMethods, swapDestinations } from "./payment-methods/Methods";
|
import { paymentMethods, swapDestinations } from './payment-methods/Methods';
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
import DashboardCustomizeIcon from '@mui/icons-material/DashboardCustomize';
|
import DashboardCustomizeIcon from '@mui/icons-material/DashboardCustomize';
|
||||||
import AddIcon from '@mui/icons-material/Add';
|
import AddIcon from '@mui/icons-material/Add';
|
||||||
import PaymentIcon from './payment-methods/Icons'
|
import PaymentIcon from './payment-methods/Icons';
|
||||||
import CheckIcon from '@mui/icons-material/Check';
|
import CheckIcon from '@mui/icons-material/Check';
|
||||||
import CloseIcon from '@mui/icons-material/Close';
|
import CloseIcon from '@mui/icons-material/Close';
|
||||||
|
|
||||||
const Root = styled('div')(
|
const Root = styled('div')(
|
||||||
({ theme }) => `
|
({ theme }) => `
|
||||||
color: ${
|
color: ${theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.65)' : 'rgba(0,0,0,.85)'};
|
||||||
theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.65)' : 'rgba(0,0,0,.85)'
|
|
||||||
};
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
`,
|
`,
|
||||||
);
|
);
|
||||||
|
|
||||||
const Label = styled('label')(
|
const Label = styled('label')(
|
||||||
({ theme , error}) => `
|
({ theme, error }) => `
|
||||||
color: ${theme.palette.mode === 'dark' ? (error? '#f44336': '#cfcfcf') : (error? '#dd0000':'#717171')};
|
color: ${
|
||||||
|
theme.palette.mode === 'dark' ? (error ? '#f44336' : '#cfcfcf') : error ? '#dd0000' : '#717171'
|
||||||
|
};
|
||||||
align: center;
|
align: center;
|
||||||
padding: 0 0 4px;
|
padding: 0 0 4px;
|
||||||
line-height: 1.5; f44336
|
line-height: 1.5; f44336
|
||||||
@ -34,11 +34,13 @@ const Label = styled('label')(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const InputWrapper = styled('div')(
|
const InputWrapper = styled('div')(
|
||||||
({ theme , error}) => `
|
({ theme, error }) => `
|
||||||
width: 244px;
|
width: 244px;
|
||||||
min-height: 44px;
|
min-height: 44px;
|
||||||
max-height: 124px;
|
max-height: 124px;
|
||||||
border: 1px solid ${theme.palette.mode === 'dark' ? (error? '#f44336': '#434343') : (error? '#dd0000':'#c4c4c4')};
|
border: 1px solid ${
|
||||||
|
theme.palette.mode === 'dark' ? (error ? '#f44336' : '#434343') : error ? '#dd0000' : '#c4c4c4'
|
||||||
|
};
|
||||||
background-color: ${theme.palette.mode === 'dark' ? '#141414' : '#fff'};
|
background-color: ${theme.palette.mode === 'dark' ? '#141414' : '#fff'};
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: 1px;
|
padding: 1px;
|
||||||
@ -47,18 +49,32 @@ const InputWrapper = styled('div')(
|
|||||||
overflow-y:auto;
|
overflow-y:auto;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: ${theme.palette.mode === 'dark' ? (error? '#f44336':'#ffffff') : (error? '#dd0000' :'#2f2f2f')};
|
border-color: ${
|
||||||
|
theme.palette.mode === 'dark'
|
||||||
|
? error
|
||||||
|
? '#f44336'
|
||||||
|
: '#ffffff'
|
||||||
|
: error
|
||||||
|
? '#dd0000'
|
||||||
|
: '#2f2f2f'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
&.focused {
|
&.focused {
|
||||||
border: 2px solid ${theme.palette.mode === 'dark' ? (error? '#f44336':'#90caf9') : (error? '#dd0000' :'#1976d2')};
|
border: 2px solid ${
|
||||||
|
theme.palette.mode === 'dark'
|
||||||
|
? error
|
||||||
|
? '#f44336'
|
||||||
|
: '#90caf9'
|
||||||
|
: error
|
||||||
|
? '#dd0000'
|
||||||
|
: '#1976d2'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
& input {
|
& input {
|
||||||
background-color: ${theme.palette.mode === 'dark' ? '#141414' : '#fff'};
|
background-color: ${theme.palette.mode === 'dark' ? '#141414' : '#fff'};
|
||||||
color: ${
|
color: ${theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.65)' : 'rgba(0,0,0,.85)'};
|
||||||
theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.65)' : 'rgba(0,0,0,.85)'
|
|
||||||
};
|
|
||||||
height: 30px;
|
height: 30px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 4px 6px;
|
padding: 4px 6px;
|
||||||
@ -78,10 +94,10 @@ function Tag(props) {
|
|||||||
const { label, icon, onDelete, ...other } = props;
|
const { label, icon, onDelete, ...other } = props;
|
||||||
return (
|
return (
|
||||||
<div {...other}>
|
<div {...other}>
|
||||||
<div style={{position:'relative',left:'-5px',top:'4px'}}>
|
<div style={{ position: 'relative', left: '-5px', top: '4px' }}>
|
||||||
<PaymentIcon width={22} height={22} icon={icon}/>
|
<PaymentIcon width={22} height={22} icon={icon} />
|
||||||
</div>
|
</div>
|
||||||
<span style={{position:'relative',left:'2px'}}>{label}</span>
|
<span style={{ position: 'relative', left: '2px' }}>{label}</span>
|
||||||
<CloseIcon onClick={onDelete} />
|
<CloseIcon onClick={onDelete} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -100,9 +116,7 @@ const StyledTag = styled(Tag)(
|
|||||||
height: 34px;
|
height: 34px;
|
||||||
margin: 2px;
|
margin: 2px;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
background-color: ${
|
background-color: ${theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.08)' : '#fafafa'};
|
||||||
theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.08)' : '#fafafa'
|
|
||||||
};
|
|
||||||
border: 1px solid ${theme.palette.mode === 'dark' ? '#303030' : '#e8e8e8'};
|
border: 1px solid ${theme.palette.mode === 'dark' ? '#303030' : '#e8e8e8'};
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
box-sizing: content-box;
|
box-sizing: content-box;
|
||||||
@ -131,7 +145,7 @@ const StyledTag = styled(Tag)(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const ListHeader = styled('span')(
|
const ListHeader = styled('span')(
|
||||||
({ theme }) => `
|
({ theme }) => `
|
||||||
color: ${theme.palette.mode === 'dark' ? '#90caf9' : '#1976d2'};
|
color: ${theme.palette.mode === 'dark' ? '#90caf9' : '#1976d2'};
|
||||||
align: left;
|
align: left;
|
||||||
line-height:10px;
|
line-height:10px;
|
||||||
@ -202,83 +216,119 @@ export default function AutocompletePayments(props) {
|
|||||||
getOptionProps,
|
getOptionProps,
|
||||||
groupedOptions,
|
groupedOptions,
|
||||||
value,
|
value,
|
||||||
focused="true",
|
focused = 'true',
|
||||||
setAnchorEl,
|
setAnchorEl,
|
||||||
} = useAutocomplete({
|
} = useAutocomplete({
|
||||||
sx: {width:'200px', align:'left'},
|
sx: { width: '200px', align: 'left' },
|
||||||
id: 'payment-methods',
|
id: 'payment-methods',
|
||||||
multiple: true,
|
multiple: true,
|
||||||
options: props.optionsType=="fiat" ? paymentMethods : swapDestinations,
|
options: props.optionsType == 'fiat' ? paymentMethods : swapDestinations,
|
||||||
getOptionLabel: (option) => option.name,
|
getOptionLabel: (option) => option.name,
|
||||||
onInputChange: (e) => setVal(e ? (e.target.value ? e.target.value : "") : ""),
|
onInputChange: (e) => setVal(e ? (e.target.value ? e.target.value : '') : ''),
|
||||||
onChange: (event, value) => props.onAutocompleteChange(optionsToString(value)),
|
onChange: (event, value) => props.onAutocompleteChange(optionsToString(value)),
|
||||||
onClose: () => (setVal(() => "")),
|
onClose: () => setVal(() => ''),
|
||||||
});
|
});
|
||||||
|
|
||||||
const [val, setVal] = useState();
|
const [val, setVal] = useState();
|
||||||
|
|
||||||
function optionsToString(newValue){
|
function optionsToString(newValue) {
|
||||||
var str = '';
|
var str = '';
|
||||||
var arrayLength = newValue.length;
|
var arrayLength = newValue.length;
|
||||||
for (var i = 0; i < arrayLength; i++) {
|
for (var i = 0; i < arrayLength; i++) {
|
||||||
str += newValue[i].name + ' ';
|
str += newValue[i].name + ' ';
|
||||||
}
|
}
|
||||||
return str.slice(0, -1);
|
return str.slice(0, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleAddNew(inputProps){
|
function handleAddNew(inputProps) {
|
||||||
paymentMethods.push({name: inputProps.value, icon:'custom'})
|
paymentMethods.push({ name: inputProps.value, icon: 'custom' });
|
||||||
var a = value.push({name: inputProps.value, icon:'custom'});
|
var a = value.push({ name: inputProps.value, icon: 'custom' });
|
||||||
setVal(() => "");
|
setVal(() => '');
|
||||||
|
|
||||||
if(a || a == null){props.onAutocompleteChange(optionsToString(value))}
|
if (a || a == null) {
|
||||||
return false
|
props.onAutocompleteChange(optionsToString(value));
|
||||||
};
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Root>
|
<Root>
|
||||||
<div style={{height:'5px'}}></div>
|
<div style={{ height: '5px' }}></div>
|
||||||
<Tooltip placement="top" enterTouchDelay={300} enterDelay={700} enterNextDelay={2000} title={props.tooltipTitle}>
|
<Tooltip
|
||||||
<div {...getRootProps()} >
|
placement='top'
|
||||||
<Label {...getInputLabelProps()} error={props.error ? "error" : null}> {props.label}</Label>
|
enterTouchDelay={300}
|
||||||
<InputWrapper ref={setAnchorEl} error={props.error ? "error" : null} className={focused ? 'focused' : ''}>
|
enterDelay={700}
|
||||||
|
enterNextDelay={2000}
|
||||||
|
title={props.tooltipTitle}
|
||||||
|
>
|
||||||
|
<div {...getRootProps()}>
|
||||||
|
<Label {...getInputLabelProps()} error={props.error ? 'error' : null}>
|
||||||
|
{' '}
|
||||||
|
{props.label}
|
||||||
|
</Label>
|
||||||
|
<InputWrapper
|
||||||
|
ref={setAnchorEl}
|
||||||
|
error={props.error ? 'error' : null}
|
||||||
|
className={focused ? 'focused' : ''}
|
||||||
|
>
|
||||||
{value.map((option, index) => (
|
{value.map((option, index) => (
|
||||||
<StyledTag label={t(option.name)} icon={option.icon} {...getTagProps({ index })} />
|
<StyledTag label={t(option.name)} icon={option.icon} {...getTagProps({ index })} />
|
||||||
))}
|
))}
|
||||||
<input {...getInputProps()} value={val ? val :""}/>
|
<input {...getInputProps()} value={val ? val : ''} />
|
||||||
</InputWrapper>
|
</InputWrapper>
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{groupedOptions.length > 0 ? (
|
{groupedOptions.length > 0 ? (
|
||||||
<Listbox {...getListboxProps()}>
|
<Listbox {...getListboxProps()}>
|
||||||
<div style={{position:'fixed', minHeight:'20px', marginLeft: 120-props.listHeaderText.length*3, marginTop: '-13px'}}>
|
<div
|
||||||
<ListHeader ><i>{props.listHeaderText+" "} </i> </ListHeader>
|
style={{
|
||||||
</div>
|
position: 'fixed',
|
||||||
|
minHeight: '20px',
|
||||||
|
marginLeft: 120 - props.listHeaderText.length * 3,
|
||||||
|
marginTop: '-13px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ListHeader>
|
||||||
|
<i>{props.listHeaderText + ' '} </i>{' '}
|
||||||
|
</ListHeader>
|
||||||
|
</div>
|
||||||
{groupedOptions.map((option, index) => (
|
{groupedOptions.map((option, index) => (
|
||||||
<li key={option.name} {...getOptionProps({ option, index })}>
|
<li key={option.name} {...getOptionProps({ option, index })}>
|
||||||
<Button fullWidth={true} color='inherit' size="small" sx={{textTransform: "none"}} style={{justifyContent: "flex-start"}}>
|
<Button
|
||||||
<div style={{position:'relative', right: '4px', top:'4px'}}>
|
fullWidth={true}
|
||||||
<AddIcon style={{color : '#1976d2'}} sx={{width:18,height:18}} />
|
color='inherit'
|
||||||
</div>
|
size='small'
|
||||||
{t(option.name)}
|
sx={{ textTransform: 'none' }}
|
||||||
|
style={{ justifyContent: 'flex-start' }}
|
||||||
|
>
|
||||||
|
<div style={{ position: 'relative', right: '4px', top: '4px' }}>
|
||||||
|
<AddIcon style={{ color: '#1976d2' }} sx={{ width: 18, height: 18 }} />
|
||||||
|
</div>
|
||||||
|
{t(option.name)}
|
||||||
</Button>
|
</Button>
|
||||||
<div style={{position:'relative', top: '5px'}}><CheckIcon/></div>
|
<div style={{ position: 'relative', top: '5px' }}>
|
||||||
|
<CheckIcon />
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
{val != null?
|
{val != null ? (
|
||||||
(val.length > 2 ?
|
val.length > 2 ? (
|
||||||
<Button size="small" fullWidth={true} onClick={() => handleAddNew(getInputProps())}><DashboardCustomizeIcon sx={{width:18,height:18}}/>{props.addNewButtonText}</Button>
|
<Button size='small' fullWidth={true} onClick={() => handleAddNew(getInputProps())}>
|
||||||
:null)
|
<DashboardCustomizeIcon sx={{ width: 18, height: 18 }} />
|
||||||
:null}
|
{props.addNewButtonText}
|
||||||
|
</Button>
|
||||||
|
) : null
|
||||||
|
) : null}
|
||||||
</Listbox>
|
</Listbox>
|
||||||
) :
|
) : //Here goes what happens if there is no groupedOptions
|
||||||
//Here goes what happens if there is no groupedOptions
|
getInputProps().value.length > 0 ? (
|
||||||
(getInputProps().value.length > 0 ?
|
|
||||||
<Listbox {...getListboxProps()}>
|
<Listbox {...getListboxProps()}>
|
||||||
<Button fullWidth={true} onClick={() => handleAddNew(getInputProps())}><DashboardCustomizeIcon sx={{width:20,height:20}}/>{props.addNewButtonText}</Button>
|
<Button fullWidth={true} onClick={() => handleAddNew(getInputProps())}>
|
||||||
|
<DashboardCustomizeIcon sx={{ width: 20, height: 20 }} />
|
||||||
|
{props.addNewButtonText}
|
||||||
|
</Button>
|
||||||
</Listbox>
|
</Listbox>
|
||||||
:null)
|
) : null}
|
||||||
}
|
|
||||||
</Root>
|
</Root>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,55 +1,77 @@
|
|||||||
import React, { useEffect, useState } from "react"
|
import React, { useEffect, useState } from 'react';
|
||||||
import { ResponsiveLine, Serie, Datum, PointTooltipProps, PointMouseHandler, Point, CustomLayer } from '@nivo/line'
|
import {
|
||||||
import { Box, CircularProgress, Grid, IconButton, MenuItem, Paper, Select, useTheme } from "@mui/material"
|
ResponsiveLine,
|
||||||
|
Serie,
|
||||||
|
Datum,
|
||||||
|
PointTooltipProps,
|
||||||
|
PointMouseHandler,
|
||||||
|
Point,
|
||||||
|
CustomLayer,
|
||||||
|
} from '@nivo/line';
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
CircularProgress,
|
||||||
|
Grid,
|
||||||
|
IconButton,
|
||||||
|
MenuItem,
|
||||||
|
Paper,
|
||||||
|
Select,
|
||||||
|
useTheme,
|
||||||
|
} from '@mui/material';
|
||||||
import { AddCircleOutline, RemoveCircleOutline } from '@mui/icons-material';
|
import { AddCircleOutline, RemoveCircleOutline } from '@mui/icons-material';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useHistory } from "react-router-dom"
|
import { useHistory } from 'react-router-dom';
|
||||||
import { Order } from "../../../models/Order.model";
|
import { Order } from '../../../models/Order.model';
|
||||||
import { LimitList } from "../../../models/Limit.model";
|
import { LimitList } from '../../../models/Limit.model';
|
||||||
import RobotAvatar from '../../Robots/RobotAvatar'
|
import RobotAvatar from '../../Robots/RobotAvatar';
|
||||||
import { amountToString } from "../../../utils/prettyNumbers";
|
import { amountToString } from '../../../utils/prettyNumbers';
|
||||||
import currencyDict from '../../../../static/assets/currencies.json';
|
import currencyDict from '../../../../static/assets/currencies.json';
|
||||||
import PaymentText from "../../PaymentText";
|
import PaymentText from '../../PaymentText';
|
||||||
import getNivoScheme from "../NivoScheme"
|
import getNivoScheme from '../NivoScheme';
|
||||||
import median from "../../../utils/match";
|
import median from '../../../utils/match';
|
||||||
|
|
||||||
interface DepthChartProps {
|
interface DepthChartProps {
|
||||||
bookLoading: boolean
|
bookLoading: boolean;
|
||||||
orders: Order[]
|
orders: Order[];
|
||||||
lastDayPremium: number | undefined
|
lastDayPremium: number | undefined;
|
||||||
currency: number
|
currency: number;
|
||||||
setAppState: (state: object) => void
|
setAppState: (state: object) => void;
|
||||||
limits: LimitList
|
limits: LimitList;
|
||||||
compact?: boolean
|
compact?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DepthChart: React.FC<DepthChartProps> = ({
|
const DepthChart: React.FC<DepthChartProps> = ({
|
||||||
bookLoading, orders, lastDayPremium, currency, setAppState, limits, compact
|
bookLoading,
|
||||||
|
orders,
|
||||||
|
lastDayPremium,
|
||||||
|
currency,
|
||||||
|
setAppState,
|
||||||
|
limits,
|
||||||
|
compact,
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation();
|
||||||
const history = useHistory()
|
const history = useHistory();
|
||||||
const theme = useTheme()
|
const theme = useTheme();
|
||||||
const [enrichedOrders, setEnrichedOrders] = useState<Order[]>([])
|
const [enrichedOrders, setEnrichedOrders] = useState<Order[]>([]);
|
||||||
const [series, setSeries] = useState<Serie[]>([])
|
const [series, setSeries] = useState<Serie[]>([]);
|
||||||
const [xRange, setXRange] = useState<number>(8)
|
const [xRange, setXRange] = useState<number>(8);
|
||||||
const [xType, setXType] = useState<string>("premium")
|
const [xType, setXType] = useState<string>('premium');
|
||||||
const [currencyCode, setCurrencyCode] = useState<number>(1)
|
const [currencyCode, setCurrencyCode] = useState<number>(1);
|
||||||
const [center, setCenter] = useState<number>(0)
|
const [center, setCenter] = useState<number>(0);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (Object.keys(limits).length === 0) {
|
if (Object.keys(limits).length === 0) {
|
||||||
fetch('/api/limits/')
|
fetch('/api/limits/')
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
setAppState({ limits: data })
|
setAppState({ limits: data });
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}, [])
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setCurrencyCode(currency === 0 ? 1 : currency)
|
setCurrencyCode(currency === 0 ? 1 : currency);
|
||||||
}, [currency])
|
}, [currency]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (Object.keys(limits).length > 0) {
|
if (Object.keys(limits).length > 0) {
|
||||||
@ -57,172 +79,176 @@ const DepthChart: React.FC<DepthChartProps> = ({
|
|||||||
// We need to transform all currencies to the same base (ex. USD), we don't have the exchange rate
|
// We need to transform all currencies to the same base (ex. USD), we don't have the exchange rate
|
||||||
// for EUR -> USD, but we know the rate of both to BTC, so we get advantage of it and apply a
|
// for EUR -> USD, but we know the rate of both to BTC, so we get advantage of it and apply a
|
||||||
// simple rule of three
|
// simple rule of three
|
||||||
order.base_amount = (order.price * limits[currencyCode].price) / limits[order.currency].price
|
order.base_amount =
|
||||||
return order
|
(order.price * limits[currencyCode].price) / limits[order.currency].price;
|
||||||
})
|
return order;
|
||||||
setEnrichedOrders(enriched)
|
});
|
||||||
|
setEnrichedOrders(enriched);
|
||||||
}
|
}
|
||||||
}, [limits, orders, currencyCode])
|
}, [limits, orders, currencyCode]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (enrichedOrders.length > 0) {
|
if (enrichedOrders.length > 0) {
|
||||||
generateSeries()
|
generateSeries();
|
||||||
}
|
}
|
||||||
}, [enrichedOrders, xRange])
|
}, [enrichedOrders, xRange]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (xType === 'base_amount') {
|
if (xType === 'base_amount') {
|
||||||
const prices: number[] = enrichedOrders.map((order) => order?.base_amount || 0)
|
const prices: number[] = enrichedOrders.map((order) => order?.base_amount || 0);
|
||||||
setCenter(~~median(prices))
|
setCenter(~~median(prices));
|
||||||
setXRange(1500)
|
setXRange(1500);
|
||||||
} else if (lastDayPremium) {
|
} else if (lastDayPremium) {
|
||||||
setCenter(lastDayPremium)
|
setCenter(lastDayPremium);
|
||||||
setXRange(8)
|
setXRange(8);
|
||||||
}
|
}
|
||||||
}, [enrichedOrders, xType, lastDayPremium, currencyCode])
|
}, [enrichedOrders, xType, lastDayPremium, currencyCode]);
|
||||||
|
|
||||||
const calculateBtc = (order: Order): number => {
|
const calculateBtc = (order: Order): number => {
|
||||||
const amount = parseInt(order.amount) || order.max_amount
|
const amount = parseInt(order.amount) || order.max_amount;
|
||||||
return amount / order.price
|
return amount / order.price;
|
||||||
}
|
};
|
||||||
|
|
||||||
const generateSeries:() => void = () => {
|
const generateSeries: () => void = () => {
|
||||||
let sortedOrders: Order[] = xType === 'base_amount' ?
|
let sortedOrders: Order[] =
|
||||||
enrichedOrders.sort((order1, order2) => (order1?.base_amount || 0) - (order2?.base_amount || 0) )
|
xType === 'base_amount'
|
||||||
: enrichedOrders.sort((order1, order2) => order1.premium - order2.premium )
|
? enrichedOrders.sort(
|
||||||
|
(order1, order2) => (order1?.base_amount || 0) - (order2?.base_amount || 0),
|
||||||
|
)
|
||||||
|
: enrichedOrders.sort((order1, order2) => order1.premium - order2.premium);
|
||||||
|
|
||||||
const sortedBuyOrders: Order[] = sortedOrders.filter((order) => order.type == 0).reverse()
|
const sortedBuyOrders: Order[] = sortedOrders.filter((order) => order.type == 0).reverse();
|
||||||
const sortedSellOrders: Order[] = sortedOrders.filter((order) => order.type == 1)
|
const sortedSellOrders: Order[] = sortedOrders.filter((order) => order.type == 1);
|
||||||
|
|
||||||
const buySerie: Datum[] = generateSerie(sortedBuyOrders)
|
const buySerie: Datum[] = generateSerie(sortedBuyOrders);
|
||||||
const sellSerie: Datum[] = generateSerie(sortedSellOrders)
|
const sellSerie: Datum[] = generateSerie(sortedSellOrders);
|
||||||
|
|
||||||
const maxX: number = center + xRange
|
const maxX: number = center + xRange;
|
||||||
const minX: number = center - xRange
|
const minX: number = center - xRange;
|
||||||
|
|
||||||
setSeries([
|
setSeries([
|
||||||
{
|
{
|
||||||
id: "buy",
|
id: 'buy',
|
||||||
data: closeSerie(buySerie, maxX, minX)
|
data: closeSerie(buySerie, maxX, minX),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "sell",
|
id: 'sell',
|
||||||
data: closeSerie(sellSerie, minX, maxX)
|
data: closeSerie(sellSerie, minX, maxX),
|
||||||
}
|
},
|
||||||
])
|
]);
|
||||||
}
|
};
|
||||||
|
|
||||||
const generateSerie = (orders: Order[]): Datum[] => {
|
const generateSerie = (orders: Order[]): Datum[] => {
|
||||||
if (!center) { return [] }
|
if (!center) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
let sumOrders: number = 0
|
let sumOrders: number = 0;
|
||||||
let serie: Datum[] = []
|
let serie: Datum[] = [];
|
||||||
orders.forEach((order) => {
|
orders.forEach((order) => {
|
||||||
const lastSumOrders = sumOrders
|
const lastSumOrders = sumOrders;
|
||||||
sumOrders += calculateBtc(order)
|
sumOrders += calculateBtc(order);
|
||||||
const datum: Datum[] = [
|
const datum: Datum[] = [
|
||||||
{ // Vertical Line
|
{
|
||||||
x: xType === 'base_amount' ? order.base_amount : order.premium,
|
// Vertical Line
|
||||||
y: lastSumOrders
|
x: xType === 'base_amount' ? order.base_amount : order.premium,
|
||||||
|
y: lastSumOrders,
|
||||||
},
|
},
|
||||||
{ // Order Point
|
{
|
||||||
x: xType === 'base_amount' ? order.base_amount : order.premium,
|
// Order Point
|
||||||
|
x: xType === 'base_amount' ? order.base_amount : order.premium,
|
||||||
y: sumOrders,
|
y: sumOrders,
|
||||||
order: order
|
order: order,
|
||||||
}
|
},
|
||||||
]
|
];
|
||||||
|
|
||||||
serie = [...serie, ...datum]
|
serie = [...serie, ...datum];
|
||||||
})
|
});
|
||||||
const inlineSerie = serie.filter((datum: Datum) => {
|
const inlineSerie = serie.filter((datum: Datum) => {
|
||||||
return (Number(datum.x) > center - xRange) &&
|
return Number(datum.x) > center - xRange && Number(datum.x) < center + xRange;
|
||||||
(Number(datum.x) < center + xRange)
|
});
|
||||||
})
|
|
||||||
|
|
||||||
return inlineSerie
|
return inlineSerie;
|
||||||
}
|
};
|
||||||
|
|
||||||
const closeSerie = (serie: Datum[], limitBottom: number, limitTop: number): Datum[] =>{
|
const closeSerie = (serie: Datum[], limitBottom: number, limitTop: number): Datum[] => {
|
||||||
if (serie.length == 0) { return [] }
|
if (serie.length == 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
// If the bottom is not 0, exdens the horizontal bottom line
|
// If the bottom is not 0, exdens the horizontal bottom line
|
||||||
if (serie[0].y !== 0) {
|
if (serie[0].y !== 0) {
|
||||||
const startingPoint: Datum = {
|
const startingPoint: Datum = {
|
||||||
x: limitBottom,
|
x: limitBottom,
|
||||||
y: serie[0].y
|
y: serie[0].y,
|
||||||
}
|
};
|
||||||
serie.unshift(startingPoint)
|
serie.unshift(startingPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
// exdens the horizontal top line
|
// exdens the horizontal top line
|
||||||
const endingPoint: Datum = {
|
const endingPoint: Datum = {
|
||||||
x: limitTop,
|
x: limitTop,
|
||||||
y: serie[serie.length - 1].y
|
y: serie[serie.length - 1].y,
|
||||||
}
|
};
|
||||||
|
|
||||||
return [...serie, endingPoint]
|
return [...serie, endingPoint];
|
||||||
}
|
};
|
||||||
|
|
||||||
const centerLine: CustomLayer = (props) => (
|
const centerLine: CustomLayer = (props) => (
|
||||||
<path
|
<path
|
||||||
key="center-line"
|
key='center-line'
|
||||||
d={props.lineGenerator([
|
d={props.lineGenerator([
|
||||||
{
|
{
|
||||||
y: 0,
|
y: 0,
|
||||||
x: props.xScale(center)
|
x: props.xScale(center),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y: props.innerHeight,
|
y: props.innerHeight,
|
||||||
x: props.xScale(center)
|
x: props.xScale(center),
|
||||||
},
|
},
|
||||||
])}
|
])}
|
||||||
fill="none"
|
fill='none'
|
||||||
stroke={getNivoScheme(theme).markers?.lineColor}
|
stroke={getNivoScheme(theme).markers?.lineColor}
|
||||||
strokeWidth={getNivoScheme(theme).markers?.lineStrokeWidth}
|
strokeWidth={getNivoScheme(theme).markers?.lineStrokeWidth}
|
||||||
/>
|
/>
|
||||||
)
|
);
|
||||||
|
|
||||||
const generateTooltip: React.FunctionComponent<PointTooltipProps> = (pointTooltip: PointTooltipProps) => {
|
const generateTooltip: React.FunctionComponent<PointTooltipProps> = (
|
||||||
const order: Order = pointTooltip.point.data.order
|
pointTooltip: PointTooltipProps,
|
||||||
|
) => {
|
||||||
|
const order: Order = pointTooltip.point.data.order;
|
||||||
return order ? (
|
return order ? (
|
||||||
<Paper elevation={12} style={{ padding: 10, width: 250 }}>
|
<Paper elevation={12} style={{ padding: 10, width: 250 }}>
|
||||||
<Grid container justifyContent="space-between">
|
<Grid container justifyContent='space-between'>
|
||||||
<Grid item xs={3}>
|
<Grid item xs={3}>
|
||||||
<Grid
|
<Grid container justifyContent='center' alignItems='center'>
|
||||||
container
|
|
||||||
justifyContent="center"
|
|
||||||
alignItems="center"
|
|
||||||
>
|
|
||||||
<RobotAvatar order={order} />
|
<RobotAvatar order={order} />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={8}>
|
<Grid item xs={8}>
|
||||||
<Grid
|
<Grid container direction='column' justifyContent='center' alignItems='flex-start'>
|
||||||
container
|
<Box>{order.maker_nick}</Box>
|
||||||
direction="column"
|
|
||||||
justifyContent="center"
|
|
||||||
alignItems="flex-start"
|
|
||||||
>
|
|
||||||
<Box>
|
|
||||||
{order.maker_nick}
|
|
||||||
</Box>
|
|
||||||
<Box>
|
<Box>
|
||||||
<Grid
|
<Grid
|
||||||
container
|
container
|
||||||
direction="column"
|
direction='column'
|
||||||
justifyContent="flex-start"
|
justifyContent='flex-start'
|
||||||
alignItems="flex-start"
|
alignItems='flex-start'
|
||||||
>
|
>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
{amountToString(order.amount, order.has_range, order.min_amount, order.max_amount)}
|
{amountToString(
|
||||||
{' '}
|
order.amount,
|
||||||
|
order.has_range,
|
||||||
|
order.min_amount,
|
||||||
|
order.max_amount,
|
||||||
|
)}{' '}
|
||||||
{currencyDict[order.currency]}
|
{currencyDict[order.currency]}
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<PaymentText
|
<PaymentText
|
||||||
othersText={t("Others")}
|
othersText={t('Others')}
|
||||||
verbose={true}
|
verbose={true}
|
||||||
size={20}
|
size={20}
|
||||||
text={order.payment_method}
|
text={order.payment_method}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
@ -232,69 +258,67 @@ const DepthChart: React.FC<DepthChartProps> = ({
|
|||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Paper>
|
</Paper>
|
||||||
) : <></>
|
) : (
|
||||||
}
|
<></>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const formatAxisX = (value: number): string => {
|
const formatAxisX = (value: number): string => {
|
||||||
if (xType === 'base_amount') {
|
if (xType === 'base_amount') {
|
||||||
return value.toString()
|
return value.toString();
|
||||||
}
|
}
|
||||||
return `${value}%`
|
return `${value}%`;
|
||||||
}
|
};
|
||||||
const formatAxisY = (value: number): string => `${value}BTC`
|
const formatAxisY = (value: number): string => `${value}BTC`;
|
||||||
|
|
||||||
const rangeSteps = xType === 'base_amount' ? 200 : 0.5
|
const rangeSteps = xType === 'base_amount' ? 200 : 0.5;
|
||||||
|
|
||||||
const handleOnClick: PointMouseHandler = (point: Point) => {
|
const handleOnClick: PointMouseHandler = (point: Point) => {
|
||||||
history.push('/order/' + point.data?.order?.id);
|
history.push('/order/' + point.data?.order?.id);
|
||||||
}
|
};
|
||||||
|
|
||||||
return bookLoading || !center || enrichedOrders.length < 1 ? (
|
return bookLoading || !center || enrichedOrders.length < 1 ? (
|
||||||
<div style={{display: "flex", justifyContent: "center", paddingTop: 200, height: 420 }}>
|
<div style={{ display: 'flex', justifyContent: 'center', paddingTop: 200, height: 420 }}>
|
||||||
<CircularProgress />
|
<CircularProgress />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<Grid container style={{ paddingTop: 15 }}>
|
<Grid container style={{ paddingTop: 15 }}>
|
||||||
<Grid
|
<Grid
|
||||||
container
|
container
|
||||||
direction="row"
|
direction='row'
|
||||||
justifyContent="space-around"
|
justifyContent='space-around'
|
||||||
alignItems="flex-start"
|
alignItems='flex-start'
|
||||||
style={{ position: "absolute" }}
|
style={{ position: 'absolute' }}
|
||||||
>
|
>
|
||||||
<Grid container justifyContent="flex-start" alignItems="flex-start" style={{ paddingLeft: 20 }}>
|
<Grid
|
||||||
<Select
|
container
|
||||||
variant="standard"
|
justifyContent='flex-start'
|
||||||
value={xType}
|
alignItems='flex-start'
|
||||||
onChange={(e) => setXType(e.target.value)}
|
style={{ paddingLeft: 20 }}
|
||||||
>
|
>
|
||||||
<MenuItem value={"premium"}>
|
<Select variant='standard' value={xType} onChange={(e) => setXType(e.target.value)}>
|
||||||
<div style={{display:'flex',alignItems:'center', flexWrap:'wrap'}}>
|
<MenuItem value={'premium'}>
|
||||||
{t("Premium")}
|
<div style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap' }}>
|
||||||
|
{t('Premium')}
|
||||||
</div>
|
</div>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem value={"base_amount"}>
|
<MenuItem value={'base_amount'}>
|
||||||
<div style={{display:'flex',alignItems:'center', flexWrap:'wrap'}}>
|
<div style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap' }}>
|
||||||
{t("Price")}
|
{t('Price')}
|
||||||
</div>
|
</div>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</Select>
|
</Select>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid
|
<Grid container direction='row' justifyContent='center' alignItems='center'>
|
||||||
container
|
<Grid container justifyContent='center' alignItems='center'>
|
||||||
direction="row"
|
|
||||||
justifyContent="center"
|
|
||||||
alignItems="center"
|
|
||||||
>
|
|
||||||
<Grid container justifyContent="center" alignItems="center">
|
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<IconButton onClick={() => setXRange(xRange + rangeSteps)}>
|
<IconButton onClick={() => setXRange(xRange + rangeSteps)}>
|
||||||
<RemoveCircleOutline />
|
<RemoveCircleOutline />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Box justifyContent="center">
|
<Box justifyContent='center'>
|
||||||
{xType === 'base_amount' ? `${center} ${currencyDict[currencyCode]}` : `${center}%`}
|
{xType === 'base_amount' ? `${center} ${currencyDict[currencyCode]}` : `${center}%`}
|
||||||
</Box>
|
</Box>
|
||||||
</Grid>
|
</Grid>
|
||||||
@ -306,42 +330,42 @@ const DepthChart: React.FC<DepthChartProps> = ({
|
|||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid container style={{ height: 357, padding: 15 }}>
|
<Grid container style={{ height: 357, padding: 15 }}>
|
||||||
<ResponsiveLine
|
<ResponsiveLine
|
||||||
data={series}
|
data={series}
|
||||||
enableArea={true}
|
enableArea={true}
|
||||||
useMesh={true}
|
useMesh={true}
|
||||||
animate={false}
|
animate={false}
|
||||||
crosshairType="cross"
|
crosshairType='cross'
|
||||||
tooltip={generateTooltip}
|
tooltip={generateTooltip}
|
||||||
onClick={handleOnClick}
|
onClick={handleOnClick}
|
||||||
axisRight={{
|
axisRight={{
|
||||||
tickSize: 5,
|
tickSize: 5,
|
||||||
format: formatAxisY
|
format: formatAxisY,
|
||||||
}}
|
}}
|
||||||
axisLeft={{
|
axisLeft={{
|
||||||
tickSize: 5,
|
tickSize: 5,
|
||||||
format: formatAxisY
|
format: formatAxisY,
|
||||||
}}
|
}}
|
||||||
axisBottom={{
|
axisBottom={{
|
||||||
tickSize: 5,
|
tickSize: 5,
|
||||||
tickRotation: xType === 'base_amount' && compact ? 45 : 0,
|
tickRotation: xType === 'base_amount' && compact ? 45 : 0,
|
||||||
format: formatAxisX
|
format: formatAxisX,
|
||||||
}}
|
}}
|
||||||
margin={{ left: 65, right: 60, bottom: compact ? 36 : 25, top: 10 }}
|
margin={{ left: 65, right: 60, bottom: compact ? 36 : 25, top: 10 }}
|
||||||
xFormat={(value) => Number(value).toFixed(0)}
|
xFormat={(value) => Number(value).toFixed(0)}
|
||||||
lineWidth={3}
|
lineWidth={3}
|
||||||
theme={getNivoScheme(theme)}
|
theme={getNivoScheme(theme)}
|
||||||
colors={[theme.palette.secondary.main,theme.palette.primary.main]}
|
colors={[theme.palette.secondary.main, theme.palette.primary.main]}
|
||||||
xScale={{
|
xScale={{
|
||||||
type: 'linear',
|
type: 'linear',
|
||||||
min: center - xRange,
|
min: center - xRange,
|
||||||
max: center + xRange
|
max: center + xRange,
|
||||||
}}
|
}}
|
||||||
layers={['axes', 'areas', 'crosshair', 'lines', centerLine, 'slices', 'mesh']}
|
layers={['axes', 'areas', 'crosshair', 'lines', centerLine, 'slices', 'mesh']}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default DepthChart
|
export default DepthChart;
|
||||||
|
@ -1,61 +1,61 @@
|
|||||||
import { light } from "@mui/material/styles/createPalette"
|
import { light } from '@mui/material/styles/createPalette';
|
||||||
import { palette } from "@mui/system"
|
import { palette } from '@mui/system';
|
||||||
import { Theme as NivoTheme } from "@nivo/core"
|
import { Theme as NivoTheme } from '@nivo/core';
|
||||||
import { Theme as MuiTheme } from './createTheme'
|
import { Theme as MuiTheme } from './createTheme';
|
||||||
|
|
||||||
export const getNivoScheme: (theme: MuiTheme) => NivoTheme = (theme) => {
|
export const getNivoScheme: (theme: MuiTheme) => NivoTheme = (theme) => {
|
||||||
const lightMode = {
|
const lightMode = {
|
||||||
markers: {
|
markers: {
|
||||||
lineColor: "rgb(0, 0, 0)",
|
lineColor: 'rgb(0, 0, 0)',
|
||||||
lineStrokeWidth: 1
|
lineStrokeWidth: 1,
|
||||||
},
|
},
|
||||||
axis: {
|
axis: {
|
||||||
ticks: {
|
ticks: {
|
||||||
line: {
|
line: {
|
||||||
strokeWidth: "1",
|
strokeWidth: '1',
|
||||||
stroke: "rgb(0, 0, 0)"
|
stroke: 'rgb(0, 0, 0)',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
domain: {
|
domain: {
|
||||||
line: {
|
line: {
|
||||||
strokeWidth: "1",
|
strokeWidth: '1',
|
||||||
stroke: "rgb(0, 0, 0)"
|
stroke: 'rgb(0, 0, 0)',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
const darkMode = {
|
const darkMode = {
|
||||||
markers: {
|
markers: {
|
||||||
lineColor: "rgb(255, 255, 255)",
|
lineColor: 'rgb(255, 255, 255)',
|
||||||
lineStrokeWidth: 1
|
lineStrokeWidth: 1,
|
||||||
},
|
},
|
||||||
axis: {
|
axis: {
|
||||||
ticks: {
|
ticks: {
|
||||||
text: {
|
text: {
|
||||||
fill: "rgb(255, 255, 255)"
|
fill: 'rgb(255, 255, 255)',
|
||||||
},
|
},
|
||||||
line: {
|
line: {
|
||||||
strokeWidth: "1",
|
strokeWidth: '1',
|
||||||
stroke: "rgb(255, 255, 255)"
|
stroke: 'rgb(255, 255, 255)',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
domain: {
|
domain: {
|
||||||
line: {
|
line: {
|
||||||
strokeWidth: "1",
|
strokeWidth: '1',
|
||||||
stroke: "rgb(255, 255, 255)"
|
stroke: 'rgb(255, 255, 255)',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
crosshair: {
|
crosshair: {
|
||||||
line: {
|
line: {
|
||||||
strokeWidth: 1,
|
strokeWidth: 1,
|
||||||
stroke: "rgb(255, 255, 255)"
|
stroke: 'rgb(255, 255, 255)',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
return theme.palette.mode === 'dark' ? darkMode : lightMode
|
return theme.palette.mode === 'dark' ? darkMode : lightMode;
|
||||||
}
|
};
|
||||||
|
|
||||||
export default getNivoScheme
|
export default getNivoScheme;
|
||||||
|
@ -1,51 +1,52 @@
|
|||||||
import React from "react";
|
import React from 'react';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
IconButton,
|
IconButton,
|
||||||
TextField,
|
TextField,
|
||||||
DialogActions,
|
DialogActions,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogContentText,
|
DialogContentText,
|
||||||
Button,
|
Button,
|
||||||
Grid,
|
Grid,
|
||||||
Link,
|
Link,
|
||||||
} from "@mui/material"
|
} from '@mui/material';
|
||||||
|
|
||||||
import { saveAsJson } from "../../utils/saveFile";
|
import { saveAsJson } from '../../utils/saveFile';
|
||||||
import { copyToClipboard } from "../../utils/clipboard";
|
import { copyToClipboard } from '../../utils/clipboard';
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
import KeyIcon from '@mui/icons-material/Key';
|
import KeyIcon from '@mui/icons-material/Key';
|
||||||
import ContentCopy from "@mui/icons-material/ContentCopy";
|
import ContentCopy from '@mui/icons-material/ContentCopy';
|
||||||
import ForumIcon from '@mui/icons-material/Forum';
|
import ForumIcon from '@mui/icons-material/Forum';
|
||||||
import { ExportIcon, NewTabIcon } from '../Icons';
|
import { ExportIcon, NewTabIcon } from '../Icons';
|
||||||
|
|
||||||
function CredentialTextfield(props){
|
function CredentialTextfield(props) {
|
||||||
return(
|
return (
|
||||||
<Grid item align="center" xs={12}>
|
<Grid item align='center' xs={12}>
|
||||||
<Tooltip placement="top" enterTouchDelay={200} enterDelay={200} title={props.tooltipTitle}>
|
<Tooltip placement='top' enterTouchDelay={200} enterDelay={200} title={props.tooltipTitle}>
|
||||||
<TextField
|
<TextField
|
||||||
sx={{width:"100%", maxWidth:"550px"}}
|
sx={{ width: '100%', maxWidth: '550px' }}
|
||||||
disabled
|
disabled
|
||||||
label={<b>{props.label}</b>}
|
label={<b>{props.label}</b>}
|
||||||
value={props.value}
|
value={props.value}
|
||||||
variant='filled'
|
variant='filled'
|
||||||
size='small'
|
size='small'
|
||||||
InputProps={{
|
InputProps={{
|
||||||
endAdornment:
|
endAdornment: (
|
||||||
<Tooltip disableHoverListener enterTouchDelay={0} title={props.copiedTitle}>
|
<Tooltip disableHoverListener enterTouchDelay={0} title={props.copiedTitle}>
|
||||||
<IconButton onClick={()=> copyToClipboard(props.value)}>
|
<IconButton onClick={() => copyToClipboard(props.value)}>
|
||||||
<ContentCopy/>
|
<ContentCopy />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>,
|
</Tooltip>
|
||||||
}}
|
),
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Grid>
|
</Grid>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@ -53,15 +54,15 @@ type Props = {
|
|||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
orderId: number;
|
orderId: number;
|
||||||
messages: array;
|
messages: array;
|
||||||
own_pub_key: string;
|
own_pub_key: string;
|
||||||
own_enc_priv_key: string;
|
own_enc_priv_key: string;
|
||||||
peer_pub_key: string;
|
peer_pub_key: string;
|
||||||
passphrase: string;
|
passphrase: string;
|
||||||
onClickBack: () => void;
|
onClickBack: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
const AuditPGPDialog = ({
|
const AuditPGPDialog = ({
|
||||||
open,
|
open,
|
||||||
onClose,
|
onClose,
|
||||||
orderId,
|
orderId,
|
||||||
messages,
|
messages,
|
||||||
@ -74,103 +75,129 @@ const AuditPGPDialog = ({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog open={open} onClose={onClose}>
|
||||||
open={open}
|
<DialogTitle>{t("Don't trust, verify")}</DialogTitle>
|
||||||
onClose={onClose}
|
|
||||||
>
|
|
||||||
<DialogTitle >
|
|
||||||
{t("Don't trust, verify")}
|
|
||||||
</DialogTitle>
|
|
||||||
|
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<DialogContentText>
|
<DialogContentText>
|
||||||
{t("Your communication is end-to-end encrypted with OpenPGP. You can verify the privacy of this chat using any tool based on the OpenPGP standard.")}
|
{t(
|
||||||
|
'Your communication is end-to-end encrypted with OpenPGP. You can verify the privacy of this chat using any tool based on the OpenPGP standard.',
|
||||||
|
)}
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
<Grid container spacing={1} align="center">
|
<Grid container spacing={1} align='center'>
|
||||||
|
<Grid item align='center' xs={12}>
|
||||||
<Grid item align="center" xs={12}>
|
<Button
|
||||||
<Button component={Link} target="_blank" href="https://learn.robosats.com/docs/pgp-encryption">{t("Learn how to verify")} <NewTabIcon sx={{width:16,height:16}}/></Button>
|
component={Link}
|
||||||
|
target='_blank'
|
||||||
|
href='https://learn.robosats.com/docs/pgp-encryption'
|
||||||
|
>
|
||||||
|
{t('Learn how to verify')} <NewTabIcon sx={{ width: 16, height: 16 }} />
|
||||||
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<CredentialTextfield
|
<CredentialTextfield
|
||||||
tooltipTitle={t("Your PGP public key. Your peer uses it to encrypt messages only you can read.")}
|
tooltipTitle={t(
|
||||||
label={t("Your public key")}
|
'Your PGP public key. Your peer uses it to encrypt messages only you can read.',
|
||||||
|
)}
|
||||||
|
label={t('Your public key')}
|
||||||
value={own_pub_key}
|
value={own_pub_key}
|
||||||
copiedTitle={t("Copied!")}/>
|
copiedTitle={t('Copied!')}
|
||||||
|
/>
|
||||||
|
|
||||||
<CredentialTextfield
|
<CredentialTextfield
|
||||||
tooltipTitle={t("Your peer PGP public key. You use it to encrypt messages only he can read and to verify your peer signed the incoming messages.")}
|
tooltipTitle={t(
|
||||||
label={t("Peer public key")}
|
'Your peer PGP public key. You use it to encrypt messages only he can read and to verify your peer signed the incoming messages.',
|
||||||
|
)}
|
||||||
|
label={t('Peer public key')}
|
||||||
value={peer_pub_key}
|
value={peer_pub_key}
|
||||||
copiedTitle={t("Copied!")}/>
|
copiedTitle={t('Copied!')}
|
||||||
|
/>
|
||||||
|
|
||||||
<CredentialTextfield
|
<CredentialTextfield
|
||||||
tooltipTitle={t("Your encrypted private key. You use it to decrypt the messages that your peer encrypted for you. You also use it to sign the messages you send.")}
|
tooltipTitle={t(
|
||||||
label={t("Your encrypted private key")}
|
'Your encrypted private key. You use it to decrypt the messages that your peer encrypted for you. You also use it to sign the messages you send.',
|
||||||
|
)}
|
||||||
|
label={t('Your encrypted private key')}
|
||||||
value={own_enc_priv_key}
|
value={own_enc_priv_key}
|
||||||
copiedTitle={t("Copied!")}/>
|
copiedTitle={t('Copied!')}
|
||||||
|
/>
|
||||||
|
|
||||||
<CredentialTextfield
|
<CredentialTextfield
|
||||||
tooltipTitle={t("The passphrase to decrypt your private key. Only you know it! Do not share. It is also your robot token.")}
|
tooltipTitle={t(
|
||||||
label={t("Your private key passphrase (keep secure!)")}
|
'The passphrase to decrypt your private key. Only you know it! Do not share. It is also your robot token.',
|
||||||
|
)}
|
||||||
|
label={t('Your private key passphrase (keep secure!)')}
|
||||||
value={passphrase}
|
value={passphrase}
|
||||||
copiedTitle={t("Copied!")}/>
|
copiedTitle={t('Copied!')}
|
||||||
|
/>
|
||||||
<br/>
|
|
||||||
<Grid item xs={6}>
|
|
||||||
<Tooltip placement="top" enterTouchDelay={0} enterDelay={1000} enterNextDelay={2000} title={t("Save credentials as a JSON file")}>
|
|
||||||
<Button
|
|
||||||
size="small"
|
|
||||||
color="primary"
|
|
||||||
variant="contained"
|
|
||||||
onClick={()=>saveAsJson(
|
|
||||||
'keys_'+orderId+'.json',
|
|
||||||
{"own_public_key": own_pub_key,
|
|
||||||
"peer_public_key":peer_pub_key,
|
|
||||||
"encrypted_private_key":own_enc_priv_key,
|
|
||||||
"passphrase":passphrase
|
|
||||||
})}>
|
|
||||||
<div style={{width:26,height:18}}>
|
|
||||||
<ExportIcon sx={{width:18,height:18}}/>
|
|
||||||
</div>
|
|
||||||
{t("Keys")}
|
|
||||||
<div style={{width:26,height:20}}>
|
|
||||||
<KeyIcon sx={{width:20,height:20}}/>
|
|
||||||
</div>
|
|
||||||
</Button>
|
|
||||||
</Tooltip>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<Grid item xs={6}>
|
|
||||||
<Tooltip placement="top" enterTouchDelay={0} enterDelay={1000} enterNextDelay={2000} title={t("Save messages as a JSON file")}>
|
|
||||||
<Button
|
|
||||||
size="small"
|
|
||||||
color="primary"
|
|
||||||
variant="contained"
|
|
||||||
onClick={()=>saveAsJson(
|
|
||||||
'messages_'+orderId+'.json',
|
|
||||||
messages)}>
|
|
||||||
<div style={{width:28,height:20}}>
|
|
||||||
<ExportIcon sx={{width:18,height:18}}/>
|
|
||||||
</div>
|
|
||||||
{t("Messages")}
|
|
||||||
<div style={{width:26,height:20}}>
|
|
||||||
<ForumIcon sx={{width:20,height:20}}/>
|
|
||||||
</div>
|
|
||||||
</Button>
|
|
||||||
</Tooltip>
|
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Tooltip
|
||||||
|
placement='top'
|
||||||
|
enterTouchDelay={0}
|
||||||
|
enterDelay={1000}
|
||||||
|
enterNextDelay={2000}
|
||||||
|
title={t('Save credentials as a JSON file')}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
size='small'
|
||||||
|
color='primary'
|
||||||
|
variant='contained'
|
||||||
|
onClick={() =>
|
||||||
|
saveAsJson('keys_' + orderId + '.json', {
|
||||||
|
own_public_key: own_pub_key,
|
||||||
|
peer_public_key: peer_pub_key,
|
||||||
|
encrypted_private_key: own_enc_priv_key,
|
||||||
|
passphrase: passphrase,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div style={{ width: 26, height: 18 }}>
|
||||||
|
<ExportIcon sx={{ width: 18, height: 18 }} />
|
||||||
|
</div>
|
||||||
|
{t('Keys')}
|
||||||
|
<div style={{ width: 26, height: 20 }}>
|
||||||
|
<KeyIcon sx={{ width: 20, height: 20 }} />
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Tooltip
|
||||||
|
placement='top'
|
||||||
|
enterTouchDelay={0}
|
||||||
|
enterDelay={1000}
|
||||||
|
enterNextDelay={2000}
|
||||||
|
title={t('Save messages as a JSON file')}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
size='small'
|
||||||
|
color='primary'
|
||||||
|
variant='contained'
|
||||||
|
onClick={() => saveAsJson('messages_' + orderId + '.json', messages)}
|
||||||
|
>
|
||||||
|
<div style={{ width: 28, height: 20 }}>
|
||||||
|
<ExportIcon sx={{ width: 18, height: 18 }} />
|
||||||
|
</div>
|
||||||
|
{t('Messages')}
|
||||||
|
<div style={{ width: 26, height: 20 }}>
|
||||||
|
<ForumIcon sx={{ width: 20, height: 20 }} />
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Button onClick={onClickBack} autoFocus>{t("Go back")}</Button>
|
<Button onClick={onClickBack} autoFocus>
|
||||||
|
{t('Go back')}
|
||||||
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
|
|
||||||
</Dialog>
|
</Dialog>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default AuditPGPDialog;
|
export default AuditPGPDialog;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from "react";
|
import React from 'react';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
@ -12,22 +12,19 @@ import {
|
|||||||
ListItemButton,
|
ListItemButton,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Typography,
|
Typography,
|
||||||
} from "@mui/material";
|
} from '@mui/material';
|
||||||
import SendIcon from '@mui/icons-material/Send';
|
import SendIcon from '@mui/icons-material/Send';
|
||||||
import GitHubIcon from '@mui/icons-material/GitHub';
|
import GitHubIcon from '@mui/icons-material/GitHub';
|
||||||
import TwitterIcon from '@mui/icons-material/Twitter';
|
import TwitterIcon from '@mui/icons-material/Twitter';
|
||||||
import RedditIcon from '@mui/icons-material/Reddit';
|
import RedditIcon from '@mui/icons-material/Reddit';
|
||||||
import Flags from 'country-flag-icons/react/3x2'
|
import Flags from 'country-flag-icons/react/3x2';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
handleClickCloseCommunity: () => void;
|
handleClickCloseCommunity: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
const CommunityDialog = ({
|
const CommunityDialog = ({ isOpen, handleClickCloseCommunity }: Props): JSX.Element => {
|
||||||
isOpen,
|
|
||||||
handleClickCloseCommunity,
|
|
||||||
}: Props): JSX.Element => {
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const flagProps = {
|
const flagProps = {
|
||||||
@ -35,7 +32,7 @@ const CommunityDialog = ({
|
|||||||
height: 30,
|
height: 30,
|
||||||
opacity: 0.85,
|
opacity: 0.85,
|
||||||
style: {
|
style: {
|
||||||
filter: "drop-shadow(2px 2px 2px #444444)",
|
filter: 'drop-shadow(2px 2px 2px #444444)',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -43,136 +40,139 @@ const CommunityDialog = ({
|
|||||||
<Dialog
|
<Dialog
|
||||||
open={isOpen}
|
open={isOpen}
|
||||||
onClose={handleClickCloseCommunity}
|
onClose={handleClickCloseCommunity}
|
||||||
aria-labelledby="community-dialog-title"
|
aria-labelledby='community-dialog-title'
|
||||||
aria-describedby="community-description"
|
aria-describedby='community-description'
|
||||||
>
|
>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<Typography component="h5" variant="h5">
|
<Typography component='h5' variant='h5'>
|
||||||
{t("Community")}
|
{t('Community')}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<Typography component="div" variant="body2">
|
<Typography component='div' variant='body2'>
|
||||||
<p>{t("Support is only offered via public channels. Join our Telegram community if you have questions or want to hang out with other cool robots. Please, use our Github Issues if you find a bug or want to see new features!")}</p>
|
<p>
|
||||||
|
{t(
|
||||||
|
'Support is only offered via public channels. Join our Telegram community if you have questions or want to hang out with other cool robots. Please, use our Github Issues if you find a bug or want to see new features!',
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<List dense>
|
<List dense>
|
||||||
<Divider/>
|
<Divider />
|
||||||
|
|
||||||
<ListItemButton
|
<ListItemButton
|
||||||
component="a"
|
component='a'
|
||||||
target="_blank"
|
target='_blank'
|
||||||
href="https://twitter.com/robosats"
|
href='https://twitter.com/robosats'
|
||||||
rel="noreferrer"
|
rel='noreferrer'
|
||||||
>
|
>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<TwitterIcon color="primary" sx={{height:32,width:32}}/>
|
<TwitterIcon color='primary' sx={{ height: 32, width: 32 }} />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
|
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={t("Follow RoboSats in Twitter")}
|
primary={t('Follow RoboSats in Twitter')}
|
||||||
secondary={t("Twitter Official Account")}
|
secondary={t('Twitter Official Account')}
|
||||||
/>
|
/>
|
||||||
</ListItemButton>
|
</ListItemButton>
|
||||||
|
|
||||||
<Divider/>
|
<Divider />
|
||||||
|
|
||||||
<ListItemButton
|
<ListItemButton
|
||||||
component="a"
|
component='a'
|
||||||
target="_blank"
|
target='_blank'
|
||||||
href="https://reddit.com/r/robosats"
|
href='https://reddit.com/r/robosats'
|
||||||
rel="noreferrer"
|
rel='noreferrer'
|
||||||
>
|
>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<RedditIcon color="primary" sx={{height:35,width:35}}/>
|
<RedditIcon color='primary' sx={{ height: 35, width: 35 }} />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
|
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={t("Join RoboSats' Subreddit")}
|
primary={t("Join RoboSats' Subreddit")}
|
||||||
secondary={t("RoboSats in Reddit")}
|
secondary={t('RoboSats in Reddit')}
|
||||||
/>
|
/>
|
||||||
</ListItemButton>
|
</ListItemButton>
|
||||||
|
|
||||||
<Divider/>
|
<Divider />
|
||||||
|
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<SendIcon color="primary" sx={{height:32,width:32}}/>
|
<SendIcon color='primary' sx={{ height: 32, width: 32 }} />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
|
|
||||||
<ListItemText secondary={t("RoboSats Telegram Communities")}>
|
<ListItemText secondary={t('RoboSats Telegram Communities')}>
|
||||||
<Tooltip title={t("Join RoboSats Spanish speaking community!") || ""}>
|
<Tooltip title={t('Join RoboSats Spanish speaking community!') || ''}>
|
||||||
<IconButton
|
<IconButton
|
||||||
component="a"
|
component='a'
|
||||||
target="_blank"
|
target='_blank'
|
||||||
href="https://t.me/robosats_es"
|
href='https://t.me/robosats_es'
|
||||||
rel="noreferrer"
|
rel='noreferrer'
|
||||||
>
|
>
|
||||||
<Flags.ES {...flagProps} />
|
<Flags.ES {...flagProps} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<Tooltip title={t("Join RoboSats Russian speaking community!") || ""}>
|
<Tooltip title={t('Join RoboSats Russian speaking community!') || ''}>
|
||||||
<IconButton
|
<IconButton
|
||||||
component="a"
|
component='a'
|
||||||
target="_blank"
|
target='_blank'
|
||||||
href="https://t.me/robosats_ru"
|
href='https://t.me/robosats_ru'
|
||||||
rel="noreferrer"
|
rel='noreferrer'
|
||||||
>
|
>
|
||||||
<Flags.RU {...flagProps} />
|
<Flags.RU {...flagProps} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<Tooltip title={t("Join RoboSats Chinese speaking community!") || ""}>
|
<Tooltip title={t('Join RoboSats Chinese speaking community!') || ''}>
|
||||||
<IconButton
|
<IconButton
|
||||||
component="a"
|
component='a'
|
||||||
target="_blank"
|
target='_blank'
|
||||||
href="https://t.me/robosats_cn"
|
href='https://t.me/robosats_cn'
|
||||||
rel="noreferrer"
|
rel='noreferrer'
|
||||||
>
|
>
|
||||||
<Flags.CN {...flagProps} />
|
<Flags.CN {...flagProps} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<Tooltip title={t("Join RoboSats English speaking community!") || ""}>
|
<Tooltip title={t('Join RoboSats English speaking community!') || ''}>
|
||||||
<IconButton
|
<IconButton
|
||||||
component="a"
|
component='a'
|
||||||
target="_blank"
|
target='_blank'
|
||||||
href="https://t.me/robosats"
|
href='https://t.me/robosats'
|
||||||
rel="noreferrer"
|
rel='noreferrer'
|
||||||
>
|
>
|
||||||
<Flags.US {...flagProps} />
|
<Flags.US {...flagProps} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<Tooltip title={t("Join RoboSats Portuguese speaking community!") || ""}>
|
<Tooltip title={t('Join RoboSats Portuguese speaking community!') || ''}>
|
||||||
<IconButton
|
<IconButton
|
||||||
component="a"
|
component='a'
|
||||||
target="_blank"
|
target='_blank'
|
||||||
href="https://t.me/robosats_pt"
|
href='https://t.me/robosats_pt'
|
||||||
rel="noreferrer"
|
rel='noreferrer'
|
||||||
>
|
>
|
||||||
<Flags.BR {...flagProps} />
|
<Flags.BR {...flagProps} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
|
||||||
<Divider/>
|
<Divider />
|
||||||
|
|
||||||
<ListItemButton
|
<ListItemButton
|
||||||
component="a"
|
component='a'
|
||||||
target="_blank"
|
target='_blank'
|
||||||
href="https://github.com/Reckless-Satoshi/robosats/issues"
|
href='https://github.com/Reckless-Satoshi/robosats/issues'
|
||||||
rel="noreferrer"
|
rel='noreferrer'
|
||||||
>
|
>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<GitHubIcon color="primary" sx={{height:32,width:32}}/>
|
<GitHubIcon color='primary' sx={{ height: 32, width: 32 }} />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
|
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={t("Tell us about a new feature or a bug")}
|
primary={t('Tell us about a new feature or a bug')}
|
||||||
secondary={t("Github Issues - The Robotic Satoshis Open Source Project")}
|
secondary={t('Github Issues - The Robotic Satoshis Open Source Project')}
|
||||||
/>
|
/>
|
||||||
</ListItemButton>
|
</ListItemButton>
|
||||||
</List>
|
</List>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from "react";
|
import React from 'react';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
@ -11,7 +11,7 @@ import {
|
|||||||
ListItem,
|
ListItem,
|
||||||
ListItemIcon,
|
ListItemIcon,
|
||||||
Typography,
|
Typography,
|
||||||
} from "@mui/material";
|
} from '@mui/material';
|
||||||
|
|
||||||
import InventoryIcon from '@mui/icons-material/Inventory';
|
import InventoryIcon from '@mui/icons-material/Inventory';
|
||||||
import SellIcon from '@mui/icons-material/Sell';
|
import SellIcon from '@mui/icons-material/Sell';
|
||||||
@ -21,7 +21,7 @@ import PriceChangeIcon from '@mui/icons-material/PriceChange';
|
|||||||
import BookIcon from '@mui/icons-material/Book';
|
import BookIcon from '@mui/icons-material/Book';
|
||||||
import LinkIcon from '@mui/icons-material/Link';
|
import LinkIcon from '@mui/icons-material/Link';
|
||||||
|
|
||||||
import { pn } from "../../utils/prettyNumbers";
|
import { pn } from '../../utils/prettyNumbers';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@ -34,7 +34,7 @@ type Props = {
|
|||||||
makerFee: number;
|
makerFee: number;
|
||||||
takerFee: number;
|
takerFee: number;
|
||||||
swapFeeRate: number;
|
swapFeeRate: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
const ExchangeSummaryDialog = ({
|
const ExchangeSummaryDialog = ({
|
||||||
isOpen,
|
isOpen,
|
||||||
@ -50,106 +50,108 @@ const ExchangeSummaryDialog = ({
|
|||||||
}: Props): JSX.Element => {
|
}: Props): JSX.Element => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
if (swapFeeRate === null || swapFeeRate === undefined) {
|
if (swapFeeRate === null || swapFeeRate === undefined) {
|
||||||
swapFeeRate = 0
|
swapFeeRate = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
open={isOpen}
|
open={isOpen}
|
||||||
onClose={handleClickCloseExchangeSummary}
|
onClose={handleClickCloseExchangeSummary}
|
||||||
aria-labelledby="exchange-summary-title"
|
aria-labelledby='exchange-summary-title'
|
||||||
aria-describedby="exchange-summary-description"
|
aria-describedby='exchange-summary-description'
|
||||||
>
|
>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<Typography component="h5" variant="h5">{t("Exchange Summary")}</Typography>
|
<Typography component='h5' variant='h5'>
|
||||||
|
{t('Exchange Summary')}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<List dense>
|
<List dense>
|
||||||
<ListItem >
|
<ListItem>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<InventoryIcon />
|
<InventoryIcon />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
|
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primaryTypographyProps={{fontSize: '14px'}}
|
primaryTypographyProps={{ fontSize: '14px' }}
|
||||||
secondaryTypographyProps={{fontSize: '12px'}}
|
secondaryTypographyProps={{ fontSize: '12px' }}
|
||||||
primary={numPublicBuyOrders}
|
primary={numPublicBuyOrders}
|
||||||
secondary={t("Public buy orders")}
|
secondary={t('Public buy orders')}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
<ListItem >
|
<ListItem>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<SellIcon />
|
<SellIcon />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
|
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primaryTypographyProps={{fontSize: '14px'}}
|
primaryTypographyProps={{ fontSize: '14px' }}
|
||||||
secondaryTypographyProps={{fontSize: '12px'}}
|
secondaryTypographyProps={{ fontSize: '12px' }}
|
||||||
primary={numPublicSellOrders}
|
primary={numPublicSellOrders}
|
||||||
secondary={t("Public sell orders")}
|
secondary={t('Public sell orders')}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
|
||||||
<Divider/>
|
<Divider />
|
||||||
|
|
||||||
<ListItem >
|
<ListItem>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<BookIcon />
|
<BookIcon />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
|
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primaryTypographyProps={{fontSize: '14px'}}
|
primaryTypographyProps={{ fontSize: '14px' }}
|
||||||
secondaryTypographyProps={{fontSize: '12px'}}
|
secondaryTypographyProps={{ fontSize: '12px' }}
|
||||||
primary={`${pn(bookLiquidity)} Sats`}
|
primary={`${pn(bookLiquidity)} Sats`}
|
||||||
secondary={t("Book liquidity")}
|
secondary={t('Book liquidity')}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
|
||||||
<Divider/>
|
<Divider />
|
||||||
|
|
||||||
<ListItem >
|
<ListItem>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<SmartToyIcon />
|
<SmartToyIcon />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
|
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primaryTypographyProps={{fontSize: '14px'}}
|
primaryTypographyProps={{ fontSize: '14px' }}
|
||||||
secondaryTypographyProps={{fontSize: '12px'}}
|
secondaryTypographyProps={{ fontSize: '12px' }}
|
||||||
primary={activeRobotsToday}
|
primary={activeRobotsToday}
|
||||||
secondary={t("Today active robots")}
|
secondary={t('Today active robots')}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
|
||||||
<Divider/>
|
<Divider />
|
||||||
|
|
||||||
<ListItem >
|
<ListItem>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<PriceChangeIcon />
|
<PriceChangeIcon />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
|
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primaryTypographyProps={{fontSize: '14px'}}
|
primaryTypographyProps={{ fontSize: '14px' }}
|
||||||
secondaryTypographyProps={{fontSize: '12px'}}
|
secondaryTypographyProps={{ fontSize: '12px' }}
|
||||||
primary={`${lastDayNonkycBtcPremium}%`}
|
primary={`${lastDayNonkycBtcPremium}%`}
|
||||||
secondary={t("24h non-KYC bitcoin premium")}
|
secondary={t('24h non-KYC bitcoin premium')}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
|
||||||
<Divider/>
|
<Divider />
|
||||||
|
|
||||||
<ListItem >
|
<ListItem>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<PercentIcon />
|
<PercentIcon />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
|
|
||||||
<Grid container >
|
<Grid container>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primaryTypographyProps={{fontSize: '14px'}}
|
primaryTypographyProps={{ fontSize: '14px' }}
|
||||||
secondaryTypographyProps={{fontSize: '12px'}}
|
secondaryTypographyProps={{ fontSize: '12px' }}
|
||||||
secondary={t("Maker fee")}
|
secondary={t('Maker fee')}
|
||||||
>
|
>
|
||||||
{(makerFee * 100).toFixed(3)}%
|
{(makerFee * 100).toFixed(3)}%
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
@ -157,9 +159,9 @@ const ExchangeSummaryDialog = ({
|
|||||||
|
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primaryTypographyProps={{fontSize: '14px'}}
|
primaryTypographyProps={{ fontSize: '14px' }}
|
||||||
secondaryTypographyProps={{fontSize: '12px'}}
|
secondaryTypographyProps={{ fontSize: '12px' }}
|
||||||
secondary={t("Taker fee")}
|
secondary={t('Taker fee')}
|
||||||
>
|
>
|
||||||
{(takerFee * 100).toFixed(3)}%
|
{(takerFee * 100).toFixed(3)}%
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
@ -169,19 +171,18 @@ const ExchangeSummaryDialog = ({
|
|||||||
|
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
<ListItem >
|
<ListItem>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<LinkIcon />
|
<LinkIcon />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
|
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primaryTypographyProps={{fontSize: '14px'}}
|
primaryTypographyProps={{ fontSize: '14px' }}
|
||||||
secondaryTypographyProps={{fontSize: '12px'}}
|
secondaryTypographyProps={{ fontSize: '12px' }}
|
||||||
primary={`${swapFeeRate.toPrecision(3)}%`}
|
primary={`${swapFeeRate.toPrecision(3)}%`}
|
||||||
secondary={t("Current onchain payout fee")}
|
secondary={t('Current onchain payout fee')}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
|
||||||
</List>
|
</List>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
import React from "react";
|
import React from 'react';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
Typography,
|
Typography,
|
||||||
Link,
|
Link,
|
||||||
DialogActions,
|
DialogActions,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
Button,
|
Button,
|
||||||
Grid,
|
Grid,
|
||||||
Accordion,
|
Accordion,
|
||||||
AccordionDetails,
|
AccordionDetails,
|
||||||
AccordionSummary,
|
AccordionSummary,
|
||||||
} from "@mui/material"
|
} from '@mui/material';
|
||||||
import SmoothImage from 'react-smooth-image'
|
import SmoothImage from 'react-smooth-image';
|
||||||
import MediaQuery from 'react-responsive'
|
import MediaQuery from 'react-responsive';
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
||||||
@ -22,213 +22,292 @@ type Props = {
|
|||||||
maxAmount: string;
|
maxAmount: string;
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
const InfoDialog = ({
|
const InfoDialog = ({ maxAmount, open, onClose }: Props): JSX.Element => {
|
||||||
maxAmount,
|
|
||||||
open,
|
|
||||||
onClose,
|
|
||||||
}: Props): JSX.Element => {
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
open={open}
|
open={open}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
aria-labelledby="info-dialog-title"
|
aria-labelledby='info-dialog-title'
|
||||||
aria-describedby="info-dialog-description"
|
aria-describedby='info-dialog-description'
|
||||||
scroll="paper">
|
scroll='paper'
|
||||||
|
>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
|
|
||||||
<MediaQuery minWidth={475}>
|
<MediaQuery minWidth={475}>
|
||||||
<Grid container>
|
<Grid container>
|
||||||
<Grid item xs={8}>
|
<Grid item xs={8}>
|
||||||
<Typography component="h4" variant="h4">{t("What is RoboSats?")}</Typography>
|
<Typography component='h4' variant='h4'>
|
||||||
<Typography component="div" variant="body2">
|
{t('What is RoboSats?')}
|
||||||
<p>{t("It is a BTC/FIAT peer-to-peer exchange over lightning.")} <br/>
|
</Typography>
|
||||||
{t("It simplifies matchmaking and minimizes the need of trust. RoboSats focuses in privacy and speed.")}</p>
|
<Typography component='div' variant='body2'>
|
||||||
|
<p>
|
||||||
|
{t('It is a BTC/FIAT peer-to-peer exchange over lightning.')} <br />
|
||||||
|
{t(
|
||||||
|
'It simplifies matchmaking and minimizes the need of trust. RoboSats focuses in privacy and speed.',
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>{t("RoboSats is an open source project ")} <Link
|
<p>
|
||||||
href='https://github.com/reckless-satoshi/robosats'>{t("(GitHub).")}</Link>
|
{t('RoboSats is an open source project ')}{' '}
|
||||||
</p>
|
<Link href='https://github.com/reckless-satoshi/robosats'>{t('(GitHub).')}</Link>
|
||||||
</Typography>
|
</p>
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={4}>
|
||||||
|
<SmoothImage
|
||||||
|
src={window.location.origin + '/static/assets/images/v0.1.2-04.png'}
|
||||||
|
imageStyles={{
|
||||||
|
borderRadius: '50%',
|
||||||
|
border: '2px solid #555',
|
||||||
|
filter: 'drop-shadow(1px 1px 1px #000000)',
|
||||||
|
height: '170px',
|
||||||
|
width: '170px',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={4}>
|
<div style={{ height: 15 }} />
|
||||||
<SmoothImage
|
|
||||||
src={window.location.origin +'/static/assets/images/v0.1.2-04.png'}
|
|
||||||
imageStyles={{borderRadius: "50%",
|
|
||||||
border: "2px solid #555",
|
|
||||||
filter: "drop-shadow(1px 1px 1px #000000)",
|
|
||||||
height: "170px",
|
|
||||||
width: "170px"}}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
<div style={{height:15}}/>
|
|
||||||
</MediaQuery>
|
</MediaQuery>
|
||||||
|
|
||||||
<MediaQuery maxWidth={474}>
|
<MediaQuery maxWidth={474}>
|
||||||
<Typography component="h4" variant="h4">{t("What is RoboSats?")}</Typography>
|
<Typography component='h4' variant='h4'>
|
||||||
<Typography component="div" variant="body2">
|
{t('What is RoboSats?')}
|
||||||
<p>{t("It is a BTC/FIAT peer-to-peer exchange over lightning.")+" "} {t("It simplifies matchmaking and minimizes the need of trust. RoboSats focuses in privacy and speed.")}</p>
|
</Typography>
|
||||||
|
<Typography component='div' variant='body2'>
|
||||||
|
<p>
|
||||||
|
{t('It is a BTC/FIAT peer-to-peer exchange over lightning.') + ' '}{' '}
|
||||||
|
{t(
|
||||||
|
'It simplifies matchmaking and minimizes the need of trust. RoboSats focuses in privacy and speed.',
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
<img
|
<img
|
||||||
width='100%'
|
width='100%'
|
||||||
src={window.location.origin +'/static/assets/images/v0.1.2-03.png'}
|
src={window.location.origin + '/static/assets/images/v0.1.2-03.png'}
|
||||||
/>
|
/>
|
||||||
<p>{t("RoboSats is an open source project ")} <Link
|
<p>
|
||||||
href='https://github.com/reckless-satoshi/robosats'>{t("(GitHub).")}</Link>
|
{t('RoboSats is an open source project ')}{' '}
|
||||||
</p>
|
<Link href='https://github.com/reckless-satoshi/robosats'>{t('(GitHub).')}</Link>
|
||||||
</Typography>
|
</p>
|
||||||
|
</Typography>
|
||||||
</MediaQuery>
|
</MediaQuery>
|
||||||
|
|
||||||
<Accordion disableGutters={true}>
|
<Accordion disableGutters={true}>
|
||||||
<AccordionSummary expandIcon={<ExpandMoreIcon/>}>
|
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||||
<Typography>
|
<Typography>{t('How does it work?')}</Typography>
|
||||||
{t("How does it work?")}
|
|
||||||
</Typography>
|
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
<AccordionDetails>
|
<AccordionDetails>
|
||||||
<Typography component="div" variant="body2">
|
<Typography component='div' variant='body2'>
|
||||||
<p> {t("AnonymousAlice01 wants to sell bitcoin. She posts a sell order. BafflingBob02 wants to buy bitcoin and he takes Alice's order. Both have to post a small bond using lightning to prove they are real robots. Then, Alice posts the trade collateral also using a lightning hold invoice. RoboSats locks the invoice until Alice confirms she received the fiat, then the satoshis are released to Bob. Enjoy your satoshis, Bob!")}</p>
|
<p>
|
||||||
<p>{t("At no point, AnonymousAlice01 and BafflingBob02 have to entrust the bitcoin funds to each other. In case they have a conflict, RoboSats staff will help resolving the dispute.")}
|
{' '}
|
||||||
{t("You can find a step-by-step description of the trade pipeline in ")}
|
{t(
|
||||||
<Link target="_blank" href='https://learn.robosats.com/docs/trade-pipeline/'>{t("How it works")}</Link>.
|
"AnonymousAlice01 wants to sell bitcoin. She posts a sell order. BafflingBob02 wants to buy bitcoin and he takes Alice's order. Both have to post a small bond using lightning to prove they are real robots. Then, Alice posts the trade collateral also using a lightning hold invoice. RoboSats locks the invoice until Alice confirms she received the fiat, then the satoshis are released to Bob. Enjoy your satoshis, Bob!",
|
||||||
{" "+t("You can also check the full guide in ")}
|
)}
|
||||||
<Link target="_blank" href='https://learn.robosats.com/read/en'>{t("How to use")}</Link>.</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
{t(
|
||||||
|
'At no point, AnonymousAlice01 and BafflingBob02 have to entrust the bitcoin funds to each other. In case they have a conflict, RoboSats staff will help resolving the dispute.',
|
||||||
|
)}
|
||||||
|
{t('You can find a step-by-step description of the trade pipeline in ')}
|
||||||
|
<Link target='_blank' href='https://learn.robosats.com/docs/trade-pipeline/'>
|
||||||
|
{t('How it works')}
|
||||||
|
</Link>
|
||||||
|
.{' ' + t('You can also check the full guide in ')}
|
||||||
|
<Link target='_blank' href='https://learn.robosats.com/read/en'>
|
||||||
|
{t('How to use')}
|
||||||
|
</Link>
|
||||||
|
.
|
||||||
|
</p>
|
||||||
</Typography>
|
</Typography>
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
<Accordion disableGutters={true}>
|
<Accordion disableGutters={true}>
|
||||||
<AccordionSummary expandIcon={<ExpandMoreIcon/>}>
|
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||||
<Typography>
|
<Typography>{t('What payment methods are accepted?')}</Typography>
|
||||||
{t("What payment methods are accepted?")
|
|
||||||
}</Typography>
|
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
<AccordionDetails>
|
<AccordionDetails>
|
||||||
<Typography component="div" variant="body2">
|
<Typography component='div' variant='body2'>
|
||||||
<p>{t("All of them as long as they are fast. You can write down your preferred payment method(s). You will have to match with a peer who also accepts that method. The step to exchange fiat has a expiry time of 24 hours before a dispute is automatically open. We highly recommend using instant fiat payment rails.")} </p>
|
<p>
|
||||||
|
{t(
|
||||||
|
'All of them as long as they are fast. You can write down your preferred payment method(s). You will have to match with a peer who also accepts that method. The step to exchange fiat has a expiry time of 24 hours before a dispute is automatically open. We highly recommend using instant fiat payment rails.',
|
||||||
|
)}{' '}
|
||||||
|
</p>
|
||||||
</Typography>
|
</Typography>
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
<Accordion disableGutters={true}>
|
<Accordion disableGutters={true}>
|
||||||
<AccordionSummary expandIcon={<ExpandMoreIcon/>}>
|
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||||
<Typography>
|
<Typography>{t('Are there trade limits?')}</Typography>
|
||||||
{t("Are there trade limits?")}
|
|
||||||
</Typography>
|
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
<AccordionDetails>
|
<AccordionDetails>
|
||||||
<Typography component="div" variant="body2">
|
<Typography component='div' variant='body2'>
|
||||||
<p>{t("Maximum single trade size is {{maxAmount}} Satoshis to minimize lightning routing failure. There is no limits to the number of trades per day. A robot can only have one order at a time. However, you can use multiple robots simultaneously in different browsers (remember to back up your robot tokens!).", {maxAmount: maxAmount})} </p>
|
<p>
|
||||||
|
{t(
|
||||||
|
'Maximum single trade size is {{maxAmount}} Satoshis to minimize lightning routing failure. There is no limits to the number of trades per day. A robot can only have one order at a time. However, you can use multiple robots simultaneously in different browsers (remember to back up your robot tokens!).',
|
||||||
|
{ maxAmount: maxAmount },
|
||||||
|
)}{' '}
|
||||||
|
</p>
|
||||||
</Typography>
|
</Typography>
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
<Accordion disableGutters={true}>
|
<Accordion disableGutters={true}>
|
||||||
<AccordionSummary expandIcon={<ExpandMoreIcon/>}>
|
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||||
<Typography>
|
<Typography>{t('What are the fees?')}</Typography>
|
||||||
{t("What are the fees?")}
|
|
||||||
</Typography>
|
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
<AccordionDetails>
|
<AccordionDetails>
|
||||||
<Typography component="div" variant="body2">
|
<Typography component='div' variant='body2'>
|
||||||
<p>{t("RoboSats total fee for an order is {{tradeFee}}%. This fee is split to be covered by both: the order maker ({{makerFee}}%) and the order taker ({{takerFee}}%). In case an onchain address is used to received the Sats a variable swap fee applies. Check the exchange details by tapping on the bottom bar icon to see the current swap fee.",{tradeFee:"0.2", makerFee:"0.025", takerFee: "0.175"})} </p>
|
<p>
|
||||||
<p>{t("Be aware your fiat payment provider might charge extra fees. In any case, the buyer bears the costs of sending fiat. That includes banking charges, transfer fees and foreign exchange spreads. The seller must receive exactly the amount stated in the order details.")} </p>
|
{t(
|
||||||
|
'RoboSats total fee for an order is {{tradeFee}}%. This fee is split to be covered by both: the order maker ({{makerFee}}%) and the order taker ({{takerFee}}%). In case an onchain address is used to received the Sats a variable swap fee applies. Check the exchange details by tapping on the bottom bar icon to see the current swap fee.',
|
||||||
|
{ tradeFee: '0.2', makerFee: '0.025', takerFee: '0.175' },
|
||||||
|
)}{' '}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{t(
|
||||||
|
'Be aware your fiat payment provider might charge extra fees. In any case, the buyer bears the costs of sending fiat. That includes banking charges, transfer fees and foreign exchange spreads. The seller must receive exactly the amount stated in the order details.',
|
||||||
|
)}{' '}
|
||||||
|
</p>
|
||||||
</Typography>
|
</Typography>
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
<Accordion disableGutters={true}>
|
<Accordion disableGutters={true}>
|
||||||
<AccordionSummary expandIcon={<ExpandMoreIcon/>}>
|
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||||
<Typography>
|
<Typography>{t('Is RoboSats private?')}</Typography>
|
||||||
{t("Is RoboSats private?")}
|
|
||||||
</Typography>
|
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
<AccordionDetails>
|
<AccordionDetails>
|
||||||
<Typography component="div" variant="body2">
|
<Typography component='div' variant='body2'>
|
||||||
<p> {t("RoboSats will never ask you for your name, country or ID. RoboSats does not custody your funds and does not care who you are. RoboSats does not collect or custody any personal data. For best anonymity use Tor Browser and access the .onion hidden service.")} </p>
|
<p>
|
||||||
<p>{t("Your trading peer is the only one who can potentially guess anything about you. Keep your chat short and concise. Avoid providing non-essential information other than strictly necessary for the fiat payment.")} </p>
|
{' '}
|
||||||
|
{t(
|
||||||
|
'RoboSats will never ask you for your name, country or ID. RoboSats does not custody your funds and does not care who you are. RoboSats does not collect or custody any personal data. For best anonymity use Tor Browser and access the .onion hidden service.',
|
||||||
|
)}{' '}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{t(
|
||||||
|
'Your trading peer is the only one who can potentially guess anything about you. Keep your chat short and concise. Avoid providing non-essential information other than strictly necessary for the fiat payment.',
|
||||||
|
)}{' '}
|
||||||
|
</p>
|
||||||
</Typography>
|
</Typography>
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
<Accordion disableGutters={true}>
|
<Accordion disableGutters={true}>
|
||||||
<AccordionSummary expandIcon={<ExpandMoreIcon/>}>
|
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||||
<Typography>
|
<Typography>{t('What are the risks?')}</Typography>
|
||||||
{t("What are the risks?")}
|
|
||||||
</Typography>
|
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
<AccordionDetails>
|
<AccordionDetails>
|
||||||
<Typography component="div" variant="body2">
|
<Typography component='div' variant='body2'>
|
||||||
<p> {t("This is an experimental application, things could go wrong. Trade small amounts!")}</p>
|
<p>
|
||||||
<p> {t("The seller faces the same charge-back risk as with any other peer-to-peer service. Paypal or credit cards are not recommended.")}</p>
|
{' '}
|
||||||
|
{t(
|
||||||
|
'This is an experimental application, things could go wrong. Trade small amounts!',
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{' '}
|
||||||
|
{t(
|
||||||
|
'The seller faces the same charge-back risk as with any other peer-to-peer service. Paypal or credit cards are not recommended.',
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
</Typography>
|
</Typography>
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
<Accordion disableGutters={true}>
|
<Accordion disableGutters={true}>
|
||||||
<AccordionSummary expandIcon={<ExpandMoreIcon/>}>
|
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||||
<Typography>
|
<Typography>{t('What is the trust model?')}</Typography>
|
||||||
{t("What is the trust model?")}
|
|
||||||
</Typography>
|
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
<AccordionDetails>
|
<AccordionDetails>
|
||||||
<Typography component="div" variant="body2">
|
<Typography component='div' variant='body2'>
|
||||||
<p> {t("The buyer and the seller never have to trust each other. Some trust on RoboSats is needed since linking the seller's hold invoice and buyer payment is not atomic (yet). In addition, disputes are solved by the RoboSats staff.")}</p>
|
<p>
|
||||||
<p> {t("To be totally clear. Trust requirements are minimized. However, there is still one way RoboSats could run away with your satoshis: by not releasing the satoshis to the buyer. It could be argued that such move is not in RoboSats' interest as it would damage the reputation for a small payout. However, you should hesitate and only trade small quantities at a time. For large amounts use an onchain escrow service such as Bisq")}</p>
|
{' '}
|
||||||
<p> {t("You can build more trust on RoboSats by inspecting the source code.")} <Link href='https://github.com/reckless-satoshi/robosats'> {t("Project source code")}</Link>. </p>
|
{t(
|
||||||
|
"The buyer and the seller never have to trust each other. Some trust on RoboSats is needed since linking the seller's hold invoice and buyer payment is not atomic (yet). In addition, disputes are solved by the RoboSats staff.",
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{' '}
|
||||||
|
{t(
|
||||||
|
"To be totally clear. Trust requirements are minimized. However, there is still one way RoboSats could run away with your satoshis: by not releasing the satoshis to the buyer. It could be argued that such move is not in RoboSats' interest as it would damage the reputation for a small payout. However, you should hesitate and only trade small quantities at a time. For large amounts use an onchain escrow service such as Bisq",
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{' '}
|
||||||
|
{t('You can build more trust on RoboSats by inspecting the source code.')}{' '}
|
||||||
|
<Link href='https://github.com/reckless-satoshi/robosats'>
|
||||||
|
{' '}
|
||||||
|
{t('Project source code')}
|
||||||
|
</Link>
|
||||||
|
.{' '}
|
||||||
|
</p>
|
||||||
</Typography>
|
</Typography>
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
<Accordion disableGutters={true}>
|
<Accordion disableGutters={true}>
|
||||||
<AccordionSummary expandIcon={<ExpandMoreIcon/>}>
|
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||||
<Typography>
|
<Typography>{t('What happens if RoboSats suddenly disappears?')}</Typography>
|
||||||
{t("What happens if RoboSats suddenly disappears?")}
|
|
||||||
</Typography>
|
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
<AccordionDetails>
|
<AccordionDetails>
|
||||||
<Typography component="div" variant="body2">
|
<Typography component='div' variant='body2'>
|
||||||
<p> {t("Your sats will return to you. Any hold invoice that is not settled would be automatically returned even if RoboSats goes down forever. This is true for both, locked bonds and trading escrows. However, there is a small window between the seller confirms FIAT RECEIVED and the moment the buyer receives the satoshis when the funds could be permanently lost if RoboSats disappears. This window is about 1 second long. Make sure to have enough inbound liquidity to avoid routing failures. If you have any problem, reach out trough the RoboSats public channels.")}</p>
|
<p>
|
||||||
|
{' '}
|
||||||
|
{t(
|
||||||
|
'Your sats will return to you. Any hold invoice that is not settled would be automatically returned even if RoboSats goes down forever. This is true for both, locked bonds and trading escrows. However, there is a small window between the seller confirms FIAT RECEIVED and the moment the buyer receives the satoshis when the funds could be permanently lost if RoboSats disappears. This window is about 1 second long. Make sure to have enough inbound liquidity to avoid routing failures. If you have any problem, reach out trough the RoboSats public channels.',
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
</Typography>
|
</Typography>
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
<Accordion disableGutters={true}>
|
<Accordion disableGutters={true}>
|
||||||
<AccordionSummary expandIcon={<ExpandMoreIcon/>}>
|
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||||
<Typography>
|
<Typography>{t('Is RoboSats legal in my country?')}</Typography>
|
||||||
{t("Is RoboSats legal in my country?")}
|
|
||||||
</Typography>
|
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
<AccordionDetails>
|
<AccordionDetails>
|
||||||
<Typography component="div" variant="body2">
|
<Typography component='div' variant='body2'>
|
||||||
<p> {t("In many countries using RoboSats is no different than using Ebay or Craiglist. Your regulation may vary. It is your responsibility to comply.")}</p>
|
<p>
|
||||||
|
{' '}
|
||||||
|
{t(
|
||||||
|
'In many countries using RoboSats is no different than using Ebay or Craiglist. Your regulation may vary. It is your responsibility to comply.',
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
</Typography>
|
</Typography>
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
<Accordion disableGutters={true}>
|
<Accordion disableGutters={true}>
|
||||||
<AccordionSummary expandIcon={<ExpandMoreIcon/>}>
|
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||||
<Typography>
|
<Typography>{t('Disclaimer')}</Typography>
|
||||||
{t("Disclaimer")}
|
|
||||||
</Typography>
|
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
<AccordionDetails>
|
<AccordionDetails>
|
||||||
<Typography component="div" variant="body2">
|
<Typography component='div' variant='body2'>
|
||||||
<p> {t("This lightning application is provided as is. It is in active development: trade with the utmost caution. There is no private support. Support is only offered via public channels ")}<Link href='https://t.me/robosats'>{t("(Telegram)")}</Link>{t(". RoboSats will never contact you. RoboSats will definitely never ask for your robot token.")}</p>
|
<p>
|
||||||
|
{' '}
|
||||||
|
{t(
|
||||||
|
'This lightning application is provided as is. It is in active development: trade with the utmost caution. There is no private support. Support is only offered via public channels ',
|
||||||
|
)}
|
||||||
|
<Link href='https://t.me/robosats'>{t('(Telegram)')}</Link>
|
||||||
|
{t(
|
||||||
|
'. RoboSats will never contact you. RoboSats will definitely never ask for your robot token.',
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
</Typography>
|
</Typography>
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Button onClick={onClose}>{t("Close")}</Button>
|
<Button onClick={onClose}>{t('Close')}</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
|
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|
||||||
</Dialog>
|
</Dialog>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default InfoDialog;
|
export default InfoDialog;
|
||||||
|
@ -1,50 +1,49 @@
|
|||||||
import React from "react";
|
import React from 'react';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
DialogActions,
|
DialogActions,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogContentText,
|
DialogContentText,
|
||||||
Button,
|
Button,
|
||||||
Link,
|
Link,
|
||||||
} from "@mui/material"
|
} from '@mui/material';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
const LearnDialog = ({
|
const LearnDialog = ({ open, onClose }: Props): JSX.Element => {
|
||||||
open,
|
|
||||||
onClose,
|
|
||||||
}: Props): JSX.Element => {
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog open={open} onClose={onClose}>
|
||||||
open={open}
|
<DialogTitle>{t('Learn RoboSats')}</DialogTitle>
|
||||||
onClose={onClose}
|
|
||||||
>
|
|
||||||
<DialogTitle>
|
|
||||||
{t("Learn RoboSats")}
|
|
||||||
</DialogTitle>
|
|
||||||
|
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<DialogContentText>
|
<DialogContentText>
|
||||||
{t("You are about to visit Learn RoboSats. It hosts tutorials and documentation to help you learn how to use RoboSats and understand how it works.")}
|
{t(
|
||||||
|
'You are about to visit Learn RoboSats. It hosts tutorials and documentation to help you learn how to use RoboSats and understand how it works.',
|
||||||
|
)}
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Button onClick={onClose}>{t("Back")}</Button>
|
<Button onClick={onClose}>{t('Back')}</Button>
|
||||||
<Button onClick={onClose} autoFocus component={Link} href="https://learn.robosats.com" target="_blank">
|
<Button
|
||||||
|
onClick={onClose}
|
||||||
|
autoFocus
|
||||||
|
component={Link}
|
||||||
|
href='https://learn.robosats.com'
|
||||||
|
target='_blank'
|
||||||
|
>
|
||||||
{t("Let's go!")}
|
{t("Let's go!")}
|
||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
|
|
||||||
</Dialog>
|
</Dialog>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default LearnDialog;
|
export default LearnDialog;
|
||||||
|
@ -1,48 +1,43 @@
|
|||||||
import React from "react";
|
import React from 'react';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
DialogActions,
|
DialogActions,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogContentText,
|
DialogContentText,
|
||||||
Button,
|
Button,
|
||||||
} from "@mui/material"
|
} from '@mui/material';
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
const NoRobotDialog = ({
|
const NoRobotDialog = ({ open, onClose }: Props): JSX.Element => {
|
||||||
open,
|
|
||||||
onClose,
|
|
||||||
}: Props): JSX.Element => {
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog open={open} onClose={onClose}>
|
||||||
open={open}
|
<DialogTitle>{t('You do not have a robot avatar')}</DialogTitle>
|
||||||
onClose={onClose}
|
|
||||||
>
|
|
||||||
<DialogTitle>
|
|
||||||
{t("You do not have a robot avatar")}
|
|
||||||
</DialogTitle>
|
|
||||||
|
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<DialogContentText>
|
<DialogContentText>
|
||||||
{t("You need to generate a robot avatar in order to become an order maker")}
|
{t('You need to generate a robot avatar in order to become an order maker')}
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Button onClick={onClose} autoFocus>{t("Go back")}</Button>
|
<Button onClick={onClose} autoFocus>
|
||||||
<Button onClick={onClose} to="/" component={Link}>{t("Generate Robot")}</Button>
|
{t('Go back')}
|
||||||
|
</Button>
|
||||||
|
<Button onClick={onClose} to='/' component={Link}>
|
||||||
|
{t('Generate Robot')}
|
||||||
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
|
|
||||||
</Dialog>
|
</Dialog>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default NoRobotDialog;
|
export default NoRobotDialog;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Link as LinkRouter } from "react-router-dom";
|
import { Link as LinkRouter } from 'react-router-dom';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Avatar,
|
Avatar,
|
||||||
@ -23,19 +23,19 @@ import {
|
|||||||
TextField,
|
TextField,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Typography,
|
Typography,
|
||||||
} from "@mui/material";
|
} from '@mui/material';
|
||||||
|
|
||||||
import BoltIcon from "@mui/icons-material/Bolt";
|
import BoltIcon from '@mui/icons-material/Bolt';
|
||||||
import NumbersIcon from "@mui/icons-material/Numbers";
|
import NumbersIcon from '@mui/icons-material/Numbers';
|
||||||
import PasswordIcon from "@mui/icons-material/Password";
|
import PasswordIcon from '@mui/icons-material/Password';
|
||||||
import ContentCopy from "@mui/icons-material/ContentCopy";
|
import ContentCopy from '@mui/icons-material/ContentCopy';
|
||||||
import PersonAddAltIcon from "@mui/icons-material/PersonAddAlt";
|
import PersonAddAltIcon from '@mui/icons-material/PersonAddAlt';
|
||||||
import EmojiEventsIcon from "@mui/icons-material/EmojiEvents";
|
import EmojiEventsIcon from '@mui/icons-material/EmojiEvents';
|
||||||
import { UserNinjaIcon, BitcoinIcon } from "../Icons";
|
import { UserNinjaIcon, BitcoinIcon } from '../Icons';
|
||||||
|
|
||||||
import { getCookie } from "../../utils/cookies";
|
import { getCookie } from '../../utils/cookies';
|
||||||
import { copyToClipboard } from "../../utils/clipboard";
|
import { copyToClipboard } from '../../utils/clipboard';
|
||||||
import { getWebln } from "../../utils/webln";
|
import { getWebln } from '../../utils/webln';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@ -44,7 +44,7 @@ type Props = {
|
|||||||
activeOrderId: string | number;
|
activeOrderId: string | number;
|
||||||
lastOrderId: string | number;
|
lastOrderId: string | number;
|
||||||
referralCode: string;
|
referralCode: string;
|
||||||
handleSubmitInvoiceClicked: (e:any, invoice: string) => void;
|
handleSubmitInvoiceClicked: (e: any, invoice: string) => void;
|
||||||
host: string;
|
host: string;
|
||||||
showRewardsSpinner: boolean;
|
showRewardsSpinner: boolean;
|
||||||
withdrawn: boolean;
|
withdrawn: boolean;
|
||||||
@ -53,7 +53,7 @@ type Props = {
|
|||||||
stealthInvoices: boolean;
|
stealthInvoices: boolean;
|
||||||
handleSetStealthInvoice: (stealth: boolean) => void;
|
handleSetStealthInvoice: (stealth: boolean) => void;
|
||||||
setAppState: (state: any) => void; // TODO: move to a ContextProvider
|
setAppState: (state: any) => void; // TODO: move to a ContextProvider
|
||||||
}
|
};
|
||||||
|
|
||||||
const ProfileDialog = ({
|
const ProfileDialog = ({
|
||||||
isOpen,
|
isOpen,
|
||||||
@ -74,24 +74,23 @@ const ProfileDialog = ({
|
|||||||
}: Props): JSX.Element => {
|
}: Props): JSX.Element => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const [rewardInvoice, setRewardInvoice] = useState<string>("");
|
const [rewardInvoice, setRewardInvoice] = useState<string>('');
|
||||||
const [showRewards, setShowRewards] = useState<boolean>(false);
|
const [showRewards, setShowRewards] = useState<boolean>(false);
|
||||||
const [openClaimRewards, setOpenClaimRewards] = useState<boolean>(false);
|
const [openClaimRewards, setOpenClaimRewards] = useState<boolean>(false);
|
||||||
const [weblnEnabled, setWeblnEnabled] = useState<boolean>(false)
|
const [weblnEnabled, setWeblnEnabled] = useState<boolean>(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getWebln()
|
getWebln().then((webln) => {
|
||||||
.then((webln) => {
|
setWeblnEnabled(webln !== undefined);
|
||||||
setWeblnEnabled(webln !== undefined)
|
});
|
||||||
})
|
}, [showRewards]);
|
||||||
}, [showRewards])
|
|
||||||
|
|
||||||
const copyTokenHandler = () => {
|
const copyTokenHandler = () => {
|
||||||
const robotToken = getCookie("robot_token");
|
const robotToken = getCookie('robot_token');
|
||||||
|
|
||||||
if (robotToken) {
|
if (robotToken) {
|
||||||
copyToClipboard(robotToken);
|
copyToClipboard(robotToken);
|
||||||
setAppState({copiedToken:true});
|
setAppState({ copiedToken: true });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -99,59 +98,71 @@ const ProfileDialog = ({
|
|||||||
copyToClipboard(`http://${host}/ref/${referralCode}`);
|
copyToClipboard(`http://${host}/ref/${referralCode}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleWeblnInvoiceClicked = async (e: any) =>{
|
const handleWeblnInvoiceClicked = async (e: any) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (earnedRewards) {
|
if (earnedRewards) {
|
||||||
const webln = await getWebln();
|
const webln = await getWebln();
|
||||||
const invoice = webln.makeInvoice(earnedRewards).then(() => {
|
const invoice = webln.makeInvoice(earnedRewards).then(() => {
|
||||||
if (invoice) {
|
if (invoice) {
|
||||||
handleSubmitInvoiceClicked(e, invoice.paymentRequest)
|
handleSubmitInvoiceClicked(e, invoice.paymentRequest);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
open={isOpen}
|
open={isOpen}
|
||||||
onClose={handleClickCloseProfile}
|
onClose={handleClickCloseProfile}
|
||||||
aria-labelledby="profile-title"
|
aria-labelledby='profile-title'
|
||||||
aria-describedby="profile-description"
|
aria-describedby='profile-description'
|
||||||
>
|
>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<Typography component="h5" variant="h5">{t("Your Profile")}</Typography>
|
<Typography component='h5' variant='h5'>
|
||||||
|
{t('Your Profile')}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<List>
|
<List>
|
||||||
<Divider/>
|
<Divider />
|
||||||
|
|
||||||
<ListItem className="profileNickname">
|
<ListItem className='profileNickname'>
|
||||||
<ListItemText secondary={t("Your robot")}>
|
<ListItemText secondary={t('Your robot')}>
|
||||||
<Typography component="h6" variant="h6">
|
<Typography component='h6' variant='h6'>
|
||||||
{nickname ? (
|
{nickname ? (
|
||||||
<div style={{position:"relative", left:"-7px"}}>
|
<div style={{ position: 'relative', left: '-7px' }}>
|
||||||
<div style={{display:"flex", alignItems:"center", justifyContent:"left", flexWrap:"wrap", width:300}}>
|
<div
|
||||||
<BoltIcon sx={{ color: "#fcba03", height: "28px", width: "24px"}} />
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'left',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
width: 300,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<BoltIcon sx={{ color: '#fcba03', height: '28px', width: '24px' }} />
|
||||||
|
|
||||||
<a>{nickname}</a>
|
<a>{nickname}</a>
|
||||||
|
|
||||||
<BoltIcon sx={{ color: "#fcba03", height: "28px", width: "24px"}} />
|
<BoltIcon sx={{ color: '#fcba03', height: '28px', width: '24px' }} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
) : null}
|
||||||
: null}
|
|
||||||
</Typography>
|
</Typography>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
|
|
||||||
<ListItemAvatar>
|
<ListItemAvatar>
|
||||||
<Avatar className="profileAvatar"
|
<Avatar
|
||||||
sx={{ width: 65, height:65 }}
|
className='profileAvatar'
|
||||||
|
sx={{ width: 65, height: 65 }}
|
||||||
alt={nickname}
|
alt={nickname}
|
||||||
src={nickname ? `${window.location.origin}/static/assets/avatars/${nickname}.png` : ""}
|
src={
|
||||||
|
nickname ? `${window.location.origin}/static/assets/avatars/${nickname}.png` : ''
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</ListItemAvatar>
|
</ListItemAvatar>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
|
||||||
<Divider/>
|
<Divider />
|
||||||
|
|
||||||
{activeOrderId ? (
|
{activeOrderId ? (
|
||||||
<ListItemButton
|
<ListItemButton
|
||||||
@ -160,94 +171,94 @@ const ProfileDialog = ({
|
|||||||
component={LinkRouter}
|
component={LinkRouter}
|
||||||
>
|
>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<Badge badgeContent="" color="primary">
|
<Badge badgeContent='' color='primary'>
|
||||||
<NumbersIcon color="primary" />
|
<NumbersIcon color='primary' />
|
||||||
</Badge>
|
</Badge>
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={t("One active order #{{orderID}}", { orderID: activeOrderId })}
|
primary={t('One active order #{{orderID}}', { orderID: activeOrderId })}
|
||||||
secondary={t("Your current order")}
|
secondary={t('Your current order')}
|
||||||
/>
|
/>
|
||||||
</ListItemButton>
|
</ListItemButton>
|
||||||
) :
|
) : lastOrderId ? (
|
||||||
lastOrderId ? (
|
<ListItemButton
|
||||||
<ListItemButton
|
onClick={handleClickCloseProfile}
|
||||||
onClick={handleClickCloseProfile}
|
to={`/order/${lastOrderId}`}
|
||||||
to={`/order/${lastOrderId}`}
|
component={LinkRouter}
|
||||||
component={LinkRouter}
|
>
|
||||||
>
|
<ListItemIcon>
|
||||||
<ListItemIcon>
|
<NumbersIcon color='primary' />
|
||||||
<NumbersIcon color="primary" />
|
</ListItemIcon>
|
||||||
</ListItemIcon>
|
<ListItemText
|
||||||
<ListItemText
|
primary={t('Your last order #{{orderID}}', { orderID: lastOrderId })}
|
||||||
primary={t("Your last order #{{orderID}}", { orderID: lastOrderId })}
|
secondary={t('Inactive order')}
|
||||||
secondary={t("Inactive order")}
|
/>
|
||||||
/>
|
</ListItemButton>
|
||||||
</ListItemButton>
|
) : (
|
||||||
) : (
|
<ListItem>
|
||||||
<ListItem>
|
<ListItemIcon>
|
||||||
<ListItemIcon>
|
<NumbersIcon />
|
||||||
<NumbersIcon />
|
</ListItemIcon>
|
||||||
</ListItemIcon>
|
<ListItemText
|
||||||
<ListItemText
|
primary={t('No active orders')}
|
||||||
primary={t("No active orders")}
|
secondary={t('You do not have previous orders')}
|
||||||
secondary={t("You do not have previous orders")}
|
/>
|
||||||
/>
|
</ListItem>
|
||||||
</ListItem>
|
)}
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<PasswordIcon />
|
<PasswordIcon />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
|
|
||||||
<ListItemText secondary={t("Your token (will not remain here)")}>
|
<ListItemText secondary={t('Your token (will not remain here)')}>
|
||||||
{getCookie("robot_token") ? (
|
{getCookie('robot_token') ? (
|
||||||
<TextField
|
<TextField
|
||||||
disabled
|
disabled
|
||||||
sx={{width:"100%", maxWidth:"450px"}}
|
sx={{ width: '100%', maxWidth: '450px' }}
|
||||||
label={t("Back it up!")}
|
label={t('Back it up!')}
|
||||||
value={getCookie("robot_token") }
|
value={getCookie('robot_token')}
|
||||||
variant="filled"
|
variant='filled'
|
||||||
size="small"
|
size='small'
|
||||||
InputProps={{
|
InputProps={{
|
||||||
endAdornment:
|
endAdornment: (
|
||||||
<Tooltip
|
<Tooltip disableHoverListener enterTouchDelay={0} title={t('Copied!') || ''}>
|
||||||
disableHoverListener
|
<IconButton onClick={copyTokenHandler}>
|
||||||
enterTouchDelay={0}
|
<ContentCopy color='inherit' />
|
||||||
title={t("Copied!") || ""}
|
</IconButton>
|
||||||
>
|
</Tooltip>
|
||||||
<IconButton onClick={copyTokenHandler}>
|
),
|
||||||
<ContentCopy color="inherit" />
|
}}
|
||||||
</IconButton>
|
|
||||||
</Tooltip>,
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
) :
|
) : (
|
||||||
t("Cannot remember")
|
t('Cannot remember')
|
||||||
}
|
)}
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
|
||||||
<Divider/>
|
<Divider />
|
||||||
|
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<UserNinjaIcon/>
|
<UserNinjaIcon />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
|
|
||||||
<ListItemText>
|
<ListItemText>
|
||||||
<Tooltip placement="top" enterTouchDelay={0} title={t("Stealth lightning invoices do not contain details about the trade except an order reference. Enable this setting if you don't want to disclose details to a custodial lightning wallet.")}>
|
<Tooltip
|
||||||
|
placement='top'
|
||||||
|
enterTouchDelay={0}
|
||||||
|
title={t(
|
||||||
|
"Stealth lightning invoices do not contain details about the trade except an order reference. Enable this setting if you don't want to disclose details to a custodial lightning wallet.",
|
||||||
|
)}
|
||||||
|
>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
labelPlacement="end"
|
labelPlacement='end'
|
||||||
label={t("Use stealth invoices")}
|
label={t('Use stealth invoices')}
|
||||||
control={
|
control={
|
||||||
<Switch
|
<Switch
|
||||||
checked={stealthInvoices}
|
checked={stealthInvoices}
|
||||||
onChange={() => handleSetStealthInvoice(!stealthInvoices)
|
onChange={() => handleSetStealthInvoice(!stealthInvoices)}
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@ -258,21 +269,19 @@ const ProfileDialog = ({
|
|||||||
|
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<BitcoinIcon/>
|
<BitcoinIcon />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
|
|
||||||
<ListItemText>
|
<ListItemText>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
labelPlacement="end"
|
labelPlacement='end'
|
||||||
label={
|
label={
|
||||||
<div style={{display:'flex', alignItems:'center'}}>
|
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||||
{t("Rewards and compensations")}
|
{t('Rewards and compensations')}
|
||||||
</div>}
|
</div>
|
||||||
|
}
|
||||||
control={
|
control={
|
||||||
<Switch
|
<Switch checked={showRewards} onChange={() => setShowRewards(!showRewards)} />
|
||||||
checked={showRewards}
|
|
||||||
onChange={()=> setShowRewards(!showRewards)}
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
@ -285,24 +294,25 @@ const ProfileDialog = ({
|
|||||||
<PersonAddAltIcon />
|
<PersonAddAltIcon />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
|
|
||||||
<ListItemText secondary={t("Share to earn 100 Sats per trade")}>
|
<ListItemText secondary={t('Share to earn 100 Sats per trade')}>
|
||||||
<TextField
|
<TextField
|
||||||
label={t("Your referral link")}
|
label={t('Your referral link')}
|
||||||
value={host+'/ref/'+referralCode}
|
value={host + '/ref/' + referralCode}
|
||||||
size="small"
|
size='small'
|
||||||
InputProps={{
|
InputProps={{
|
||||||
endAdornment:
|
endAdornment: (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
disableHoverListener
|
disableHoverListener
|
||||||
enterTouchDelay={0}
|
enterTouchDelay={0}
|
||||||
title={t("Copied!") || ""}
|
title={t('Copied!') || ''}
|
||||||
>
|
>
|
||||||
<IconButton onClick={copyReferralCodeHandler}>
|
<IconButton onClick={copyReferralCodeHandler}>
|
||||||
<ContentCopy />
|
<ContentCopy />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>,
|
</Tooltip>
|
||||||
}}
|
),
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
|
||||||
@ -312,7 +322,7 @@ const ProfileDialog = ({
|
|||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
|
|
||||||
{!openClaimRewards ? (
|
{!openClaimRewards ? (
|
||||||
<ListItemText secondary={t("Your earned rewards")}>
|
<ListItemText secondary={t('Your earned rewards')}>
|
||||||
<Grid container>
|
<Grid container>
|
||||||
<Grid item xs={9}>
|
<Grid item xs={9}>
|
||||||
<Typography>{`${earnedRewards} Sats`}</Typography>
|
<Typography>{`${earnedRewards} Sats`}</Typography>
|
||||||
@ -322,54 +332,56 @@ const ProfileDialog = ({
|
|||||||
<Button
|
<Button
|
||||||
disabled={earnedRewards === 0 ? true : false}
|
disabled={earnedRewards === 0 ? true : false}
|
||||||
onClick={() => setOpenClaimRewards(true)}
|
onClick={() => setOpenClaimRewards(true)}
|
||||||
variant="contained"
|
variant='contained'
|
||||||
size="small"
|
size='small'
|
||||||
>
|
>
|
||||||
{t("Claim")}
|
{t('Claim')}
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
) : (
|
) : (
|
||||||
<form noValidate style={{maxWidth: 270}}>
|
<form noValidate style={{ maxWidth: 270 }}>
|
||||||
<Grid container style={{ display: "flex", alignItems: "stretch"}}>
|
<Grid container style={{ display: 'flex', alignItems: 'stretch' }}>
|
||||||
<Grid item style={{ display: "flex", maxWidth:160}} >
|
<Grid item style={{ display: 'flex', maxWidth: 160 }}>
|
||||||
<TextField
|
<TextField
|
||||||
error={badInvoice ? true : false}
|
error={badInvoice ? true : false}
|
||||||
helperText={badInvoice ? badInvoice : "" }
|
helperText={badInvoice ? badInvoice : ''}
|
||||||
label={t("Invoice for {{amountSats}} Sats", { amountSats: earnedRewards })}
|
label={t('Invoice for {{amountSats}} Sats', {
|
||||||
size="small"
|
amountSats: earnedRewards,
|
||||||
|
})}
|
||||||
|
size='small'
|
||||||
value={rewardInvoice}
|
value={rewardInvoice}
|
||||||
onChange={e => {
|
onChange={(e) => {
|
||||||
setRewardInvoice(e.target.value);
|
setRewardInvoice(e.target.value);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item alignItems="stretch" style={{ display: "flex", maxWidth:80}}>
|
<Grid item alignItems='stretch' style={{ display: 'flex', maxWidth: 80 }}>
|
||||||
<Button
|
<Button
|
||||||
sx={{maxHeight:38}}
|
sx={{ maxHeight: 38 }}
|
||||||
onClick={(e) => handleSubmitInvoiceClicked(e, rewardInvoice)}
|
onClick={(e) => handleSubmitInvoiceClicked(e, rewardInvoice)}
|
||||||
variant="contained"
|
variant='contained'
|
||||||
color="primary"
|
color='primary'
|
||||||
size="small"
|
size='small'
|
||||||
type="submit"
|
type='submit'
|
||||||
>
|
>
|
||||||
{t("Submit")}
|
{t('Submit')}
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
{weblnEnabled && (
|
{weblnEnabled && (
|
||||||
<Grid container style={{ display: "flex", alignItems: "stretch"}}>
|
<Grid container style={{ display: 'flex', alignItems: 'stretch' }}>
|
||||||
<Grid item alignItems="stretch" style={{ display: "flex", maxWidth:240}}>
|
<Grid item alignItems='stretch' style={{ display: 'flex', maxWidth: 240 }}>
|
||||||
<Button
|
<Button
|
||||||
sx={{maxHeight:38, minWidth: 230}}
|
sx={{ maxHeight: 38, minWidth: 230 }}
|
||||||
onClick={(e) => handleWeblnInvoiceClicked(e)}
|
onClick={(e) => handleWeblnInvoiceClicked(e)}
|
||||||
variant="contained"
|
variant='contained'
|
||||||
color="primary"
|
color='primary'
|
||||||
size="small"
|
size='small'
|
||||||
type="submit"
|
type='submit'
|
||||||
>
|
>
|
||||||
{t("Generate with Webln")}
|
{t('Generate with Webln')}
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
@ -379,15 +391,15 @@ const ProfileDialog = ({
|
|||||||
</ListItem>
|
</ListItem>
|
||||||
|
|
||||||
{showRewardsSpinner && (
|
{showRewardsSpinner && (
|
||||||
<div style={{display: "flex", justifyContent: "center"}}>
|
<div style={{ display: 'flex', justifyContent: 'center' }}>
|
||||||
<CircularProgress />
|
<CircularProgress />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{withdrawn && (
|
{withdrawn && (
|
||||||
<div style={{display: "flex", justifyContent: "center"}}>
|
<div style={{ display: 'flex', justifyContent: 'center' }}>
|
||||||
<Typography color="primary" variant="body2">
|
<Typography color='primary' variant='body2'>
|
||||||
<b>{t("There it goes, thank you!🥇")}</b>
|
<b>{t('There it goes, thank you!🥇')}</b>
|
||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from "react";
|
import React from 'react';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
@ -11,19 +11,19 @@ import {
|
|||||||
ListItem,
|
ListItem,
|
||||||
ListItemIcon,
|
ListItemIcon,
|
||||||
Typography,
|
Typography,
|
||||||
} from "@mui/material";
|
} from '@mui/material';
|
||||||
|
|
||||||
import BoltIcon from "@mui/icons-material/Bolt";
|
import BoltIcon from '@mui/icons-material/Bolt';
|
||||||
import PublicIcon from "@mui/icons-material/Public";
|
import PublicIcon from '@mui/icons-material/Public';
|
||||||
import DnsIcon from "@mui/icons-material/Dns";
|
import DnsIcon from '@mui/icons-material/Dns';
|
||||||
import WebIcon from "@mui/icons-material/Web";
|
import WebIcon from '@mui/icons-material/Web';
|
||||||
import FavoriteIcon from "@mui/icons-material/Favorite";
|
import FavoriteIcon from '@mui/icons-material/Favorite';
|
||||||
import GitHubIcon from "@mui/icons-material/GitHub";
|
import GitHubIcon from '@mui/icons-material/GitHub';
|
||||||
import EqualizerIcon from "@mui/icons-material/Equalizer";
|
import EqualizerIcon from '@mui/icons-material/Equalizer';
|
||||||
|
|
||||||
import { AmbossIcon, BitcoinSignIcon } from "../Icons";
|
import { AmbossIcon, BitcoinSignIcon } from '../Icons';
|
||||||
|
|
||||||
import { pn } from "../../utils/prettyNumbers";
|
import { pn } from '../../utils/prettyNumbers';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@ -37,7 +37,7 @@ type Props = {
|
|||||||
robosatsRunningCommitHash: string;
|
robosatsRunningCommitHash: string;
|
||||||
lastDayVolume: number;
|
lastDayVolume: number;
|
||||||
lifetimeVolume: number;
|
lifetimeVolume: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
const StatsDialog = ({
|
const StatsDialog = ({
|
||||||
isOpen,
|
isOpen,
|
||||||
@ -58,11 +58,13 @@ const StatsDialog = ({
|
|||||||
<Dialog
|
<Dialog
|
||||||
open={isOpen}
|
open={isOpen}
|
||||||
onClose={handleClickCloseStatsForNerds}
|
onClose={handleClickCloseStatsForNerds}
|
||||||
aria-labelledby="stats-for-nerds-dialog-title"
|
aria-labelledby='stats-for-nerds-dialog-title'
|
||||||
aria-describedby="stats-for-nerds-description"
|
aria-describedby='stats-for-nerds-description'
|
||||||
>
|
>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<Typography component="h5" variant="h5">{t("Stats For Nerds")}</Typography>
|
<Typography component='h5' variant='h5'>
|
||||||
|
{t('Stats For Nerds')}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<List dense>
|
<List dense>
|
||||||
<Divider />
|
<Divider />
|
||||||
@ -71,21 +73,21 @@ const StatsDialog = ({
|
|||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<BoltIcon />
|
<BoltIcon />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText primary={lndVersion} secondary={t("LND version")} />
|
<ListItemText primary={lndVersion} secondary={t('LND version')} />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
{network === "testnet" ? (
|
{network === 'testnet' ? (
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<DnsIcon />
|
<DnsIcon />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText secondary={nodeAlias}>
|
<ListItemText secondary={nodeAlias}>
|
||||||
<Link
|
<Link
|
||||||
target="_blank"
|
target='_blank'
|
||||||
href={`https://1ml.com/testnet/node/${nodeId}`}
|
href={`https://1ml.com/testnet/node/${nodeId}`}
|
||||||
rel="noreferrer"
|
rel='noreferrer'
|
||||||
>
|
>
|
||||||
{`${nodeId.slice(0, 12)}... (1ML)`}
|
{`${nodeId.slice(0, 12)}... (1ML)`}
|
||||||
</Link>
|
</Link>
|
||||||
@ -97,11 +99,7 @@ const StatsDialog = ({
|
|||||||
<AmbossIcon />
|
<AmbossIcon />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText secondary={nodeAlias}>
|
<ListItemText secondary={nodeAlias}>
|
||||||
<Link
|
<Link target='_blank' href={`https://amboss.space/node/${nodeId}`} rel='noreferrer'>
|
||||||
target="_blank"
|
|
||||||
href={`https://amboss.space/node/${nodeId}`}
|
|
||||||
rel="noreferrer"
|
|
||||||
>
|
|
||||||
{`${nodeId.slice(0, 12)}... (AMBOSS)`}
|
{`${nodeId.slice(0, 12)}... (AMBOSS)`}
|
||||||
</Link>
|
</Link>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
@ -115,11 +113,7 @@ const StatsDialog = ({
|
|||||||
<WebIcon />
|
<WebIcon />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText secondary={alternativeName}>
|
<ListItemText secondary={alternativeName}>
|
||||||
<Link
|
<Link target='_blank' href={`http://${alternativeSite}`} rel='noreferrer'>
|
||||||
target="_blank"
|
|
||||||
href={`http://${alternativeSite}`}
|
|
||||||
rel="noreferrer"
|
|
||||||
>
|
|
||||||
{`${alternativeSite.slice(0, 12)}...onion`}
|
{`${alternativeSite.slice(0, 12)}...onion`}
|
||||||
</Link>
|
</Link>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
@ -131,11 +125,11 @@ const StatsDialog = ({
|
|||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<GitHubIcon />
|
<GitHubIcon />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText secondary={t("Currently running commit hash")}>
|
<ListItemText secondary={t('Currently running commit hash')}>
|
||||||
<Link
|
<Link
|
||||||
target="_blank"
|
target='_blank'
|
||||||
href={`https://github.com/Reckless-Satoshi/robosats/tree/${robosatsRunningCommitHash}`}
|
href={`https://github.com/Reckless-Satoshi/robosats/tree/${robosatsRunningCommitHash}`}
|
||||||
rel="noreferrer"
|
rel='noreferrer'
|
||||||
>
|
>
|
||||||
{`${robosatsRunningCommitHash.slice(0, 12)}...`}
|
{`${robosatsRunningCommitHash.slice(0, 12)}...`}
|
||||||
</Link>
|
</Link>
|
||||||
@ -148,10 +142,17 @@ const StatsDialog = ({
|
|||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<EqualizerIcon />
|
<EqualizerIcon />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText secondary={t("24h contracted volume")}>
|
<ListItemText secondary={t('24h contracted volume')}>
|
||||||
<div style={{ cursor: "pointer", display: "flex", alignItems: "center", flexWrap: "wrap" }}>
|
<div
|
||||||
|
style={{
|
||||||
|
cursor: 'pointer',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
}}
|
||||||
|
>
|
||||||
{pn(lastDayVolume)}
|
{pn(lastDayVolume)}
|
||||||
<BitcoinSignIcon sx={{ width: 14,height: 14 }} color={"text.secondary"} />
|
<BitcoinSignIcon sx={{ width: 14, height: 14 }} color={'text.secondary'} />
|
||||||
</div>
|
</div>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
@ -162,10 +163,17 @@ const StatsDialog = ({
|
|||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<EqualizerIcon />
|
<EqualizerIcon />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText secondary={t("Lifetime contracted volume")}>
|
<ListItemText secondary={t('Lifetime contracted volume')}>
|
||||||
<div style={{ cursor: "pointer", display: "flex",alignItems: "center", flexWrap: "wrap" }}>
|
<div
|
||||||
|
style={{
|
||||||
|
cursor: 'pointer',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
}}
|
||||||
|
>
|
||||||
{pn(lifetimeVolume)}
|
{pn(lifetimeVolume)}
|
||||||
<BitcoinSignIcon sx={{ width: 14, height: 14 }} color={"text.secondary"} />
|
<BitcoinSignIcon sx={{ width: 14, height: 14 }} color={'text.secondary'} />
|
||||||
</div>
|
</div>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
@ -177,14 +185,21 @@ const StatsDialog = ({
|
|||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={
|
primary={
|
||||||
<div style={{ display: "flex", alignItems: "center", justifyContent: "left", flexWrap: "wrap" }}>
|
<div
|
||||||
<span>{`${t("Made with")} `}</span>
|
style={{
|
||||||
<FavoriteIcon sx={{ color: "#ff0000", height: "22px", width: "22px" }} />
|
display: 'flex',
|
||||||
<span>{` ${t("and")} `}</span>
|
alignItems: 'center',
|
||||||
<BoltIcon sx={{ color: "#fcba03", height: "23px",width: "23px" }} />
|
justifyContent: 'left',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span>{`${t('Made with')} `}</span>
|
||||||
|
<FavoriteIcon sx={{ color: '#ff0000', height: '22px', width: '22px' }} />
|
||||||
|
<span>{` ${t('and')} `}</span>
|
||||||
|
<BoltIcon sx={{ color: '#fcba03', height: '23px', width: '23px' }} />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
secondary={t("... somewhere on Earth!")}
|
secondary={t('... somewhere on Earth!')}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</List>
|
</List>
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
import React from "react";
|
import React from 'react';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
IconButton,
|
IconButton,
|
||||||
TextField,
|
TextField,
|
||||||
DialogActions,
|
DialogActions,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogContentText,
|
DialogContentText,
|
||||||
Button,
|
Button,
|
||||||
Grid,
|
Grid,
|
||||||
} from "@mui/material"
|
} from '@mui/material';
|
||||||
import { getCookie } from "../../utils/cookies";
|
import { getCookie } from '../../utils/cookies';
|
||||||
import ContentCopy from "@mui/icons-material/ContentCopy";
|
import ContentCopy from '@mui/icons-material/ContentCopy';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@ -22,10 +22,10 @@ type Props = {
|
|||||||
onClickCopy: () => void;
|
onClickCopy: () => void;
|
||||||
onClickBack: () => void;
|
onClickBack: () => void;
|
||||||
onClickDone: () => void;
|
onClickDone: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
const StoreTokenDialog = ({
|
const StoreTokenDialog = ({
|
||||||
open,
|
open,
|
||||||
onClose,
|
onClose,
|
||||||
copyIconColor,
|
copyIconColor,
|
||||||
onClickCopy,
|
onClickCopy,
|
||||||
@ -35,46 +35,45 @@ const StoreTokenDialog = ({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog open={open} onClose={onClose}>
|
||||||
open={open}
|
<DialogTitle>{t('Store your robot token')}</DialogTitle>
|
||||||
onClose={onClose}
|
|
||||||
>
|
|
||||||
<DialogTitle >
|
|
||||||
{t("Store your robot token")}
|
|
||||||
</DialogTitle>
|
|
||||||
|
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<DialogContentText>
|
<DialogContentText>
|
||||||
{t("You might need to recover your robot avatar in the future: store it safely. You can simply copy it into another application.")}
|
{t(
|
||||||
|
'You might need to recover your robot avatar in the future: store it safely. You can simply copy it into another application.',
|
||||||
|
)}
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
<br/>
|
<br />
|
||||||
<Grid align="center">
|
<Grid align='center'>
|
||||||
<TextField
|
<TextField
|
||||||
sx={{width:"100%", maxWidth:"550px"}}
|
sx={{ width: '100%', maxWidth: '550px' }}
|
||||||
disabled
|
disabled
|
||||||
label={t("Back it up!")}
|
label={t('Back it up!')}
|
||||||
value={getCookie("robot_token")}
|
value={getCookie('robot_token')}
|
||||||
variant='filled'
|
variant='filled'
|
||||||
size='small'
|
size='small'
|
||||||
InputProps={{
|
InputProps={{
|
||||||
endAdornment:
|
endAdornment: (
|
||||||
<Tooltip disableHoverListener enterTouchDelay={0} title={t("Copied!")}>
|
<Tooltip disableHoverListener enterTouchDelay={0} title={t('Copied!')}>
|
||||||
<IconButton onClick={onClickCopy}>
|
<IconButton onClick={onClickCopy}>
|
||||||
<ContentCopy color={copyIconColor}/>
|
<ContentCopy color={copyIconColor} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>,
|
</Tooltip>
|
||||||
}}
|
),
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Button onClick={onClickBack} autoFocus>{t("Go back")}</Button>
|
<Button onClick={onClickBack} autoFocus>
|
||||||
<Button onClick={onClickDone}>{t("Done")}</Button>
|
{t('Go back')}
|
||||||
|
</Button>
|
||||||
|
<Button onClick={onClickDone}>{t('Done')}</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
|
|
||||||
</Dialog>
|
</Dialog>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default StoreTokenDialog;
|
export default StoreTokenDialog;
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
export { default as AuditPGPDialog } from "./AuditPGP";
|
export { default as AuditPGPDialog } from './AuditPGP';
|
||||||
export { default as CommunityDialog } from "./Community";
|
export { default as CommunityDialog } from './Community';
|
||||||
export { default as InfoDialog } from "./Info";
|
export { default as InfoDialog } from './Info';
|
||||||
export { default as LearnDialog } from "./Learn";
|
export { default as LearnDialog } from './Learn';
|
||||||
export { default as NoRobotDialog } from "./NoRobot";
|
export { default as NoRobotDialog } from './NoRobot';
|
||||||
export { default as StoreTokenDialog } from "./StoreToken";
|
export { default as StoreTokenDialog } from './StoreToken';
|
||||||
export { default as ExchangeSummaryDialog } from "./ExchangeSummary";
|
export { default as ExchangeSummaryDialog } from './ExchangeSummary';
|
||||||
export { default as ProfileDialog } from "./Profile";
|
export { default as ProfileDialog } from './Profile';
|
||||||
export { default as StatsDialog } from "./Stats";
|
export { default as StatsDialog } from './Stats';
|
||||||
|
|
||||||
|
@ -1,17 +1,30 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { withTranslation } from "react-i18next";
|
import { withTranslation } from 'react-i18next';
|
||||||
import {Button, IconButton, Badge, Tooltip, TextField, Grid, Container, Card, CardHeader, Paper, Avatar, Typography} from "@mui/material";
|
import {
|
||||||
|
Button,
|
||||||
|
IconButton,
|
||||||
|
Badge,
|
||||||
|
Tooltip,
|
||||||
|
TextField,
|
||||||
|
Grid,
|
||||||
|
Container,
|
||||||
|
Card,
|
||||||
|
CardHeader,
|
||||||
|
Paper,
|
||||||
|
Avatar,
|
||||||
|
Typography,
|
||||||
|
} from '@mui/material';
|
||||||
import ReconnectingWebSocket from 'reconnecting-websocket';
|
import ReconnectingWebSocket from 'reconnecting-websocket';
|
||||||
import { encryptMessage , decryptMessage} from "../utils/pgp";
|
import { encryptMessage, decryptMessage } from '../utils/pgp';
|
||||||
import { getCookie } from "../utils/cookies";
|
import { getCookie } from '../utils/cookies';
|
||||||
import { saveAsJson } from "../utils/saveFile";
|
import { saveAsJson } from '../utils/saveFile';
|
||||||
import { copyToClipboard } from "../utils/clipboard";
|
import { copyToClipboard } from '../utils/clipboard';
|
||||||
import { AuditPGPDialog } from "./Dialogs"
|
import { AuditPGPDialog } from './Dialogs';
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
import CheckIcon from '@mui/icons-material/Check';
|
import CheckIcon from '@mui/icons-material/Check';
|
||||||
import CloseIcon from '@mui/icons-material/Close';
|
import CloseIcon from '@mui/icons-material/Close';
|
||||||
import ContentCopy from "@mui/icons-material/ContentCopy";
|
import ContentCopy from '@mui/icons-material/ContentCopy';
|
||||||
import VisibilityIcon from '@mui/icons-material/Visibility';
|
import VisibilityIcon from '@mui/icons-material/Visibility';
|
||||||
import CircularProgress from '@mui/material/CircularProgress';
|
import CircularProgress from '@mui/material/CircularProgress';
|
||||||
import KeyIcon from '@mui/icons-material/Key';
|
import KeyIcon from '@mui/icons-material/Key';
|
||||||
@ -23,120 +36,157 @@ class Chat extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
own_pub_key: getCookie('pub_key').split('\\').join('\n'),
|
own_pub_key: getCookie('pub_key').split('\\').join('\n'),
|
||||||
own_enc_priv_key: getCookie('enc_priv_key').split('\\').join('\n'),
|
own_enc_priv_key: getCookie('enc_priv_key').split('\\').join('\n'),
|
||||||
peer_pub_key: null,
|
peer_pub_key: null,
|
||||||
token: getCookie('robot_token'),
|
token: getCookie('robot_token'),
|
||||||
messages: [],
|
messages: [],
|
||||||
value:'',
|
value: '',
|
||||||
connected: false,
|
connected: false,
|
||||||
peer_connected: false,
|
peer_connected: false,
|
||||||
audit: false,
|
audit: false,
|
||||||
showPGP: new Array,
|
showPGP: new Array(),
|
||||||
waitingEcho: false,
|
waitingEcho: false,
|
||||||
lastSent: '---BLANK---',
|
lastSent: '---BLANK---',
|
||||||
latestIndex: 0,
|
latestIndex: 0,
|
||||||
scrollNow:false,
|
scrollNow: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
rws = new ReconnectingWebSocket('ws://' + window.location.host + '/ws/chat/' + this.props.orderId + '/', [], {connectionTimeout: 15000});
|
rws = new ReconnectingWebSocket(
|
||||||
|
'ws://' + window.location.host + '/ws/chat/' + this.props.orderId + '/',
|
||||||
|
[],
|
||||||
|
{ connectionTimeout: 15000 },
|
||||||
|
);
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.rws.addEventListener('open', () => {
|
this.rws.addEventListener('open', () => {
|
||||||
console.log('Connected!');
|
console.log('Connected!');
|
||||||
this.setState({connected: true});
|
this.setState({ connected: true });
|
||||||
this.rws.send(JSON.stringify({
|
this.rws.send(
|
||||||
type: "message",
|
JSON.stringify({
|
||||||
message: this.state.own_pub_key,
|
type: 'message',
|
||||||
nick: this.props.ur_nick,
|
message: this.state.own_pub_key,
|
||||||
}));
|
nick: this.props.ur_nick,
|
||||||
|
}),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.rws.addEventListener('message', (message) => {
|
this.rws.addEventListener('message', (message) => {
|
||||||
|
|
||||||
const dataFromServer = JSON.parse(message.data);
|
const dataFromServer = JSON.parse(message.data);
|
||||||
console.log('Got reply!', dataFromServer.type);
|
console.log('Got reply!', dataFromServer.type);
|
||||||
console.log('PGP message index', dataFromServer.index, ' latestIndex ',this.state.latestIndex);
|
console.log(
|
||||||
if (dataFromServer){
|
'PGP message index',
|
||||||
console.log(dataFromServer)
|
dataFromServer.index,
|
||||||
this.setState({peer_connected: dataFromServer.peer_connected})
|
' latestIndex ',
|
||||||
|
this.state.latestIndex,
|
||||||
|
);
|
||||||
|
if (dataFromServer) {
|
||||||
|
console.log(dataFromServer);
|
||||||
|
this.setState({ peer_connected: dataFromServer.peer_connected });
|
||||||
|
|
||||||
// If we receive our own key on a message
|
// If we receive our own key on a message
|
||||||
if (dataFromServer.message == this.state.own_pub_key){console.log("OWN PUB KEY RECEIVED!!")}
|
if (dataFromServer.message == this.state.own_pub_key) {
|
||||||
|
console.log('OWN PUB KEY RECEIVED!!');
|
||||||
|
}
|
||||||
|
|
||||||
// If we receive a public key other than ours (our peer key!)
|
// If we receive a public key other than ours (our peer key!)
|
||||||
if (dataFromServer.message.substring(0,36) == `-----BEGIN PGP PUBLIC KEY BLOCK-----` && dataFromServer.message != this.state.own_pub_key) {
|
if (
|
||||||
if (dataFromServer.message == this.state.peer_pub_key){
|
dataFromServer.message.substring(0, 36) == `-----BEGIN PGP PUBLIC KEY BLOCK-----` &&
|
||||||
console.log("PEER HAS RECONNECTED USING HIS PREVIOUSLY KNOWN PUBKEY")
|
dataFromServer.message != this.state.own_pub_key
|
||||||
} else if (dataFromServer.message != this.state.peer_pub_key & this.state.peer_pub_key != null){
|
) {
|
||||||
console.log("PEER PUBKEY HAS CHANGED")
|
if (dataFromServer.message == this.state.peer_pub_key) {
|
||||||
|
console.log('PEER HAS RECONNECTED USING HIS PREVIOUSLY KNOWN PUBKEY');
|
||||||
|
} else if (
|
||||||
|
(dataFromServer.message != this.state.peer_pub_key) &
|
||||||
|
(this.state.peer_pub_key != null)
|
||||||
|
) {
|
||||||
|
console.log('PEER PUBKEY HAS CHANGED');
|
||||||
}
|
}
|
||||||
console.log("PEER PUBKEY RECEIVED!!")
|
console.log('PEER PUBKEY RECEIVED!!');
|
||||||
this.setState({peer_pub_key:dataFromServer.message})
|
this.setState({ peer_pub_key: dataFromServer.message });
|
||||||
|
|
||||||
// After receiving the peer pubkey we ask the server for the historic messages if any
|
// After receiving the peer pubkey we ask the server for the historic messages if any
|
||||||
this.rws.send(JSON.stringify({
|
this.rws.send(
|
||||||
type: "message",
|
JSON.stringify({
|
||||||
|
type: 'message',
|
||||||
message: `-----SERVE HISTORY-----`,
|
message: `-----SERVE HISTORY-----`,
|
||||||
nick: this.props.ur_nick,
|
nick: this.props.ur_nick,
|
||||||
}))
|
}),
|
||||||
} else
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// If we receive an encrypted message
|
// If we receive an encrypted message
|
||||||
if (dataFromServer.message.substring(0,27) == `-----BEGIN PGP MESSAGE-----` && dataFromServer.index > this.state.latestIndex){
|
else if (
|
||||||
|
dataFromServer.message.substring(0, 27) == `-----BEGIN PGP MESSAGE-----` &&
|
||||||
|
dataFromServer.index > this.state.latestIndex
|
||||||
|
) {
|
||||||
decryptMessage(
|
decryptMessage(
|
||||||
dataFromServer.message.split('\\').join('\n'),
|
dataFromServer.message.split('\\').join('\n'),
|
||||||
dataFromServer.user_nick == this.props.ur_nick ? this.state.own_pub_key : this.state.peer_pub_key,
|
dataFromServer.user_nick == this.props.ur_nick
|
||||||
this.state.own_enc_priv_key,
|
? this.state.own_pub_key
|
||||||
this.state.token)
|
: this.state.peer_pub_key,
|
||||||
.then((decryptedData) =>
|
this.state.own_enc_priv_key,
|
||||||
this.setState((state) =>
|
this.state.token,
|
||||||
({
|
).then((decryptedData) =>
|
||||||
|
this.setState((state) => ({
|
||||||
scrollNow: true,
|
scrollNow: true,
|
||||||
waitingEcho: this.state.waitingEcho == true ? (decryptedData.decryptedMessage == this.state.lastSent ? false: true ) : false,
|
waitingEcho:
|
||||||
lastSent: decryptedData.decryptedMessage == this.state.lastSent ? '----BLANK----': this.state.lastSent,
|
this.state.waitingEcho == true
|
||||||
latestIndex: dataFromServer.index > this.state.latestIndex ? dataFromServer.index : this.state.latestIndex,
|
? decryptedData.decryptedMessage == this.state.lastSent
|
||||||
messages: [...state.messages,
|
? false
|
||||||
{
|
: true
|
||||||
index: dataFromServer.index,
|
: false,
|
||||||
encryptedMessage: dataFromServer.message.split('\\').join('\n'),
|
lastSent:
|
||||||
plainTextMessage: decryptedData.decryptedMessage,
|
decryptedData.decryptedMessage == this.state.lastSent
|
||||||
validSignature: decryptedData.validSignature,
|
? '----BLANK----'
|
||||||
userNick: dataFromServer.user_nick,
|
: this.state.lastSent,
|
||||||
time: dataFromServer.time
|
latestIndex:
|
||||||
}].sort(function(a,b) {
|
dataFromServer.index > this.state.latestIndex
|
||||||
|
? dataFromServer.index
|
||||||
|
: this.state.latestIndex,
|
||||||
|
messages: [
|
||||||
|
...state.messages,
|
||||||
|
{
|
||||||
|
index: dataFromServer.index,
|
||||||
|
encryptedMessage: dataFromServer.message.split('\\').join('\n'),
|
||||||
|
plainTextMessage: decryptedData.decryptedMessage,
|
||||||
|
validSignature: decryptedData.validSignature,
|
||||||
|
userNick: dataFromServer.user_nick,
|
||||||
|
time: dataFromServer.time,
|
||||||
|
},
|
||||||
|
].sort(function (a, b) {
|
||||||
// order the message array by their index (increasing)
|
// order the message array by their index (increasing)
|
||||||
return a.index - b.index
|
return a.index - b.index;
|
||||||
}),
|
}),
|
||||||
})
|
})),
|
||||||
));
|
);
|
||||||
|
}
|
||||||
} else
|
|
||||||
|
|
||||||
// We allow plaintext communication. The user must write # to start
|
// We allow plaintext communication. The user must write # to start
|
||||||
// If we receive an plaintext message
|
// If we receive an plaintext message
|
||||||
if (dataFromServer.message.substring(0,1) == "#"){
|
else if (dataFromServer.message.substring(0, 1) == '#') {
|
||||||
console.log("Got plaintext message", dataFromServer.message)
|
console.log('Got plaintext message', dataFromServer.message);
|
||||||
this.setState((state) =>
|
this.setState((state) => ({
|
||||||
({
|
scrollNow: true,
|
||||||
scrollNow: true,
|
messages: [
|
||||||
messages: [...state.messages,
|
...state.messages,
|
||||||
{
|
{
|
||||||
index: this.state.latestIndex + 0.001,
|
index: this.state.latestIndex + 0.001,
|
||||||
encryptedMessage: dataFromServer.message,
|
encryptedMessage: dataFromServer.message,
|
||||||
plainTextMessage: dataFromServer.message,
|
plainTextMessage: dataFromServer.message,
|
||||||
validSignature: false,
|
validSignature: false,
|
||||||
userNick: dataFromServer.user_nick,
|
userNick: dataFromServer.user_nick,
|
||||||
time: (new Date).toString(),
|
time: new Date().toString(),
|
||||||
}]}));
|
},
|
||||||
}
|
],
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.rws.addEventListener('close', () => {
|
this.rws.addEventListener('close', () => {
|
||||||
console.log('Socket is closed. Reconnect will be attempted');
|
console.log('Socket is closed. Reconnect will be attempted');
|
||||||
this.setState({connected: false});
|
this.setState({ connected: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
this.rws.addEventListener('error', () => {
|
this.rws.addEventListener('error', () => {
|
||||||
@ -145,216 +195,401 @@ class Chat extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
|
|
||||||
// Only fire the scroll and audio when the reason for Update is a new message
|
// Only fire the scroll and audio when the reason for Update is a new message
|
||||||
if (this.state.scrollNow){
|
if (this.state.scrollNow) {
|
||||||
const audio = new Audio(`/static/assets/sounds/chat-open.mp3`)
|
const audio = new Audio(`/static/assets/sounds/chat-open.mp3`);
|
||||||
audio.play();
|
audio.play();
|
||||||
this.scrollToBottom();
|
this.scrollToBottom();
|
||||||
this.setState({scrollNow:false});
|
this.setState({ scrollNow: false });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollToBottom = () => {
|
scrollToBottom = () => {
|
||||||
this.messagesEnd.scrollIntoView({ behavior: "smooth" });
|
this.messagesEnd.scrollIntoView({ behavior: 'smooth' });
|
||||||
}
|
};
|
||||||
|
|
||||||
onButtonClicked = (e) => {
|
onButtonClicked = (e) => {
|
||||||
// If input string contains token. Do not set message
|
// If input string contains token. Do not set message
|
||||||
if(this.state.value.indexOf(this.state.token) !== -1){
|
if (this.state.value.indexOf(this.state.token) !== -1) {
|
||||||
alert(`Aye! You just sent your own robot token to your peer in chat, that's a catastrophic idea! So bad your message was blocked.`)
|
alert(
|
||||||
this.setState({value: ""});
|
`Aye! You just sent your own robot token to your peer in chat, that's a catastrophic idea! So bad your message was blocked.`,
|
||||||
|
);
|
||||||
|
this.setState({ value: '' });
|
||||||
}
|
}
|
||||||
|
|
||||||
// If input string contains '#' send unencrypted and unlogged message
|
// If input string contains '#' send unencrypted and unlogged message
|
||||||
else if(this.state.value.substring(0,1)=='#'){
|
else if (this.state.value.substring(0, 1) == '#') {
|
||||||
this.rws.send(JSON.stringify({
|
this.rws.send(
|
||||||
type: "message",
|
JSON.stringify({
|
||||||
|
type: 'message',
|
||||||
message: this.state.value,
|
message: this.state.value,
|
||||||
nick: this.props.ur_nick,
|
nick: this.props.ur_nick,
|
||||||
}));
|
}),
|
||||||
this.setState({value: ""});
|
);
|
||||||
|
this.setState({ value: '' });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Else if message is not empty send message
|
// Else if message is not empty send message
|
||||||
else if(this.state.value!=''){
|
else if (this.state.value != '') {
|
||||||
this.setState({value: "", waitingEcho: true, lastSent:this.state.value})
|
this.setState({ value: '', waitingEcho: true, lastSent: this.state.value });
|
||||||
encryptMessage(this.state.value, this.state.own_pub_key, this.state.peer_pub_key, this.state.own_enc_priv_key, this.state.token)
|
encryptMessage(
|
||||||
.then((encryptedMessage) =>
|
this.state.value,
|
||||||
console.log("Sending Encrypted MESSAGE", encryptedMessage) &
|
this.state.own_pub_key,
|
||||||
this.rws.send(JSON.stringify({
|
this.state.peer_pub_key,
|
||||||
type: "message",
|
this.state.own_enc_priv_key,
|
||||||
message: encryptedMessage.split('\n').join('\\'),
|
this.state.token,
|
||||||
nick: this.props.ur_nick,
|
).then(
|
||||||
})
|
(encryptedMessage) =>
|
||||||
)
|
console.log('Sending Encrypted MESSAGE', encryptedMessage) &
|
||||||
|
this.rws.send(
|
||||||
|
JSON.stringify({
|
||||||
|
type: 'message',
|
||||||
|
message: encryptedMessage.split('\n').join('\\'),
|
||||||
|
nick: this.props.ur_nick,
|
||||||
|
}),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
};
|
||||||
|
|
||||||
createJsonFile = () => {
|
createJsonFile = () => {
|
||||||
return ({
|
return {
|
||||||
"credentials": {
|
credentials: {
|
||||||
"own_public_key": this.state.own_pub_key,
|
own_public_key: this.state.own_pub_key,
|
||||||
"peer_public_key":this.state.peer_pub_key,
|
peer_public_key: this.state.peer_pub_key,
|
||||||
"encrypted_private_key":this.state.own_enc_priv_key,
|
encrypted_private_key: this.state.own_enc_priv_key,
|
||||||
"passphrase":this.state.token},
|
passphrase: this.state.token,
|
||||||
"messages": this.state.messages,
|
},
|
||||||
})
|
messages: this.state.messages,
|
||||||
}
|
};
|
||||||
|
};
|
||||||
|
|
||||||
messageCard = (props) => {
|
messageCard = (props) => {
|
||||||
const { t } = this.props;
|
const { t } = this.props;
|
||||||
return(
|
return (
|
||||||
<Card elevation={5} align="left" >
|
<Card elevation={5} align='left'>
|
||||||
<CardHeader sx={{color: '#333333'}}
|
<CardHeader
|
||||||
|
sx={{ color: '#333333' }}
|
||||||
avatar={
|
avatar={
|
||||||
<Badge variant="dot" overlap="circular" badgeContent="" color={props.userConnected ? "success" : "error"}>
|
<Badge
|
||||||
<Avatar className="flippedSmallAvatar"
|
variant='dot'
|
||||||
|
overlap='circular'
|
||||||
|
badgeContent=''
|
||||||
|
color={props.userConnected ? 'success' : 'error'}
|
||||||
|
>
|
||||||
|
<Avatar
|
||||||
|
className='flippedSmallAvatar'
|
||||||
alt={props.message.userNick}
|
alt={props.message.userNick}
|
||||||
src={window.location.origin +'/static/assets/avatars/' + props.message.userNick + '.png'}
|
src={
|
||||||
/>
|
window.location.origin +
|
||||||
|
'/static/assets/avatars/' +
|
||||||
|
props.message.userNick +
|
||||||
|
'.png'
|
||||||
|
}
|
||||||
|
/>
|
||||||
</Badge>
|
</Badge>
|
||||||
}
|
}
|
||||||
style={{backgroundColor: props.cardColor}}
|
style={{ backgroundColor: props.cardColor }}
|
||||||
title={
|
title={
|
||||||
<Tooltip placement="top" enterTouchDelay={0} enterDelay={500} enterNextDelay={2000} title={t(props.message.validSignature ? "Verified signature by {{nickname}}": "Cannot verify signature of {{nickname}}",{"nickname": props.message.userNick})}>
|
<Tooltip
|
||||||
<div style={{display:'flex',alignItems:'center', flexWrap:'wrap', position:'relative',left:-5, width:240}}>
|
placement='top'
|
||||||
<div style={{width:168,display:'flex',alignItems:'center', flexWrap:'wrap'}}>
|
enterTouchDelay={0}
|
||||||
|
enterDelay={500}
|
||||||
|
enterNextDelay={2000}
|
||||||
|
title={t(
|
||||||
|
props.message.validSignature
|
||||||
|
? 'Verified signature by {{nickname}}'
|
||||||
|
: 'Cannot verify signature of {{nickname}}',
|
||||||
|
{ nickname: props.message.userNick },
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
position: 'relative',
|
||||||
|
left: -5,
|
||||||
|
width: 240,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{ width: 168, display: 'flex', alignItems: 'center', flexWrap: 'wrap' }}
|
||||||
|
>
|
||||||
{props.message.userNick}
|
{props.message.userNick}
|
||||||
{props.message.validSignature ?
|
{props.message.validSignature ? (
|
||||||
<CheckIcon sx={{height:16}} color="success"/>
|
<CheckIcon sx={{ height: 16 }} color='success' />
|
||||||
:
|
) : (
|
||||||
<CloseIcon sx={{height:16}} color="error"/>
|
<CloseIcon sx={{ height: 16 }} color='error' />
|
||||||
}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div style={{width:20}}>
|
<div style={{ width: 20 }}>
|
||||||
<IconButton sx={{height:18,width:18}}
|
<IconButton
|
||||||
onClick={()=>
|
sx={{ height: 18, width: 18 }}
|
||||||
this.setState(prevState => {
|
onClick={() =>
|
||||||
const newShowPGP = [...prevState.showPGP];
|
this.setState((prevState) => {
|
||||||
newShowPGP[props.index] = !newShowPGP[props.index];
|
const newShowPGP = [...prevState.showPGP];
|
||||||
return {showPGP: newShowPGP};
|
newShowPGP[props.index] = !newShowPGP[props.index];
|
||||||
})}>
|
return { showPGP: newShowPGP };
|
||||||
<VisibilityIcon color={this.state.showPGP[props.index]? "primary":"inherit"} sx={{height:16,width:16,color:this.state.showPGP[props.index]? "primary":"#333333"}}/>
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<VisibilityIcon
|
||||||
|
color={this.state.showPGP[props.index] ? 'primary' : 'inherit'}
|
||||||
|
sx={{
|
||||||
|
height: 16,
|
||||||
|
width: 16,
|
||||||
|
color: this.state.showPGP[props.index] ? 'primary' : '#333333',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</div>
|
</div>
|
||||||
<div style={{width:20}}>
|
<div style={{ width: 20 }}>
|
||||||
<Tooltip disableHoverListener enterTouchDelay={0} title={t("Copied!")}>
|
<Tooltip disableHoverListener enterTouchDelay={0} title={t('Copied!')}>
|
||||||
<IconButton sx={{height:18,width:18}}
|
<IconButton
|
||||||
onClick={()=> copyToClipboard(this.state.showPGP[props.index] ? props.message.encryptedMessage : props.message.plainTextMessage)}>
|
sx={{ height: 18, width: 18 }}
|
||||||
<ContentCopy sx={{height:16,width:16,color:'#333333'}}/>
|
onClick={() =>
|
||||||
|
copyToClipboard(
|
||||||
|
this.state.showPGP[props.index]
|
||||||
|
? props.message.encryptedMessage
|
||||||
|
: props.message.plainTextMessage,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<ContentCopy sx={{ height: 16, width: 16, color: '#333333' }} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
}
|
}
|
||||||
subheader={this.state.showPGP[props.index] ? <a> {props.message.time} <br/> {"Valid signature: " + props.message.validSignature} <br/> {props.message.encryptedMessage} </a> : props.message.plainTextMessage}
|
subheader={
|
||||||
subheaderTypographyProps={{sx: {wordWrap: "break-word", width: '200px', color: '#444444', fontSize: this.state.showPGP[props.index]? 11 : null }}}
|
this.state.showPGP[props.index] ? (
|
||||||
|
<a>
|
||||||
|
{' '}
|
||||||
|
{props.message.time} <br /> {'Valid signature: ' + props.message.validSignature}{' '}
|
||||||
|
<br /> {props.message.encryptedMessage}{' '}
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
props.message.plainTextMessage
|
||||||
|
)
|
||||||
|
}
|
||||||
|
subheaderTypographyProps={{
|
||||||
|
sx: {
|
||||||
|
wordWrap: 'break-word',
|
||||||
|
width: '200px',
|
||||||
|
color: '#444444',
|
||||||
|
fontSize: this.state.showPGP[props.index] ? 11 : null,
|
||||||
|
},
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { t } = this.props;
|
const { t } = this.props;
|
||||||
return (
|
return (
|
||||||
<Container component="main">
|
<Container component='main'>
|
||||||
<Grid container spacing={0.5}>
|
<Grid container spacing={0.5}>
|
||||||
<Grid item xs={0.3}/>
|
<Grid item xs={0.3} />
|
||||||
<Grid item xs={5.5}>
|
<Grid item xs={5.5}>
|
||||||
<Paper elevation={1} style={this.state.connected ? {backgroundColor: '#e8ffe6'}: {backgroundColor: '#FFF1C5'}}>
|
<Paper
|
||||||
<Typography variant='caption' sx={{color: '#333333'}}>
|
elevation={1}
|
||||||
{t("You")+": "}{this.state.connected ? t("connected"): t("disconnected")}
|
style={
|
||||||
</Typography>
|
this.state.connected
|
||||||
</Paper>
|
? { backgroundColor: '#e8ffe6' }
|
||||||
</Grid>
|
: { backgroundColor: '#FFF1C5' }
|
||||||
<Grid item xs={0.4}/>
|
|
||||||
<Grid item xs={5.5}>
|
|
||||||
<Paper elevation={1} style={this.state.peer_connected ? {backgroundColor: '#e8ffe6'}: {backgroundColor: '#FFF1C5'}}>
|
|
||||||
<Typography variant='caption' sx={{color: '#333333'}}>
|
|
||||||
{t("Peer")+": "}{this.state.peer_connected ? t("connected"): t("disconnected")}
|
|
||||||
</Typography>
|
|
||||||
</Paper>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={0.3}/>
|
|
||||||
</Grid>
|
|
||||||
<div style={{position:'relative', left:'-2px', margin:'0 auto', width: '285px'}}>
|
|
||||||
<Paper elevation={1} style={{height: '300px', maxHeight: '300px' , width: '285px' ,overflow: 'auto', backgroundColor: '#F7F7F7' }}>
|
|
||||||
{this.state.messages.map((message, index) =>
|
|
||||||
<li style={{listStyleType:"none"}} key={index}>
|
|
||||||
{message.userNick == this.props.ur_nick ?
|
|
||||||
<this.messageCard message={message} index={index} cardColor={'#eeeeee'} userConnected={this.state.connected}/>
|
|
||||||
:
|
|
||||||
<this.messageCard message={message} index={index} cardColor={'#fafafa'} userConnected={this.state.peer_connected}/>
|
|
||||||
}
|
}
|
||||||
</li>)}
|
>
|
||||||
<div style={{ float:"left", clear: "both" }} ref={(el) => { this.messagesEnd = el; }}></div>
|
<Typography variant='caption' sx={{ color: '#333333' }}>
|
||||||
|
{t('You') + ': '}
|
||||||
|
{this.state.connected ? t('connected') : t('disconnected')}
|
||||||
|
</Typography>
|
||||||
|
</Paper>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={0.4} />
|
||||||
|
<Grid item xs={5.5}>
|
||||||
|
<Paper
|
||||||
|
elevation={1}
|
||||||
|
style={
|
||||||
|
this.state.peer_connected
|
||||||
|
? { backgroundColor: '#e8ffe6' }
|
||||||
|
: { backgroundColor: '#FFF1C5' }
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Typography variant='caption' sx={{ color: '#333333' }}>
|
||||||
|
{t('Peer') + ': '}
|
||||||
|
{this.state.peer_connected ? t('connected') : t('disconnected')}
|
||||||
|
</Typography>
|
||||||
|
</Paper>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={0.3} />
|
||||||
|
</Grid>
|
||||||
|
<div style={{ position: 'relative', left: '-2px', margin: '0 auto', width: '285px' }}>
|
||||||
|
<Paper
|
||||||
|
elevation={1}
|
||||||
|
style={{
|
||||||
|
height: '300px',
|
||||||
|
maxHeight: '300px',
|
||||||
|
width: '285px',
|
||||||
|
overflow: 'auto',
|
||||||
|
backgroundColor: '#F7F7F7',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{this.state.messages.map((message, index) => (
|
||||||
|
<li style={{ listStyleType: 'none' }} key={index}>
|
||||||
|
{message.userNick == this.props.ur_nick ? (
|
||||||
|
<this.messageCard
|
||||||
|
message={message}
|
||||||
|
index={index}
|
||||||
|
cardColor={'#eeeeee'}
|
||||||
|
userConnected={this.state.connected}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<this.messageCard
|
||||||
|
message={message}
|
||||||
|
index={index}
|
||||||
|
cardColor={'#fafafa'}
|
||||||
|
userConnected={this.state.peer_connected}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
<div
|
||||||
|
style={{ float: 'left', clear: 'both' }}
|
||||||
|
ref={(el) => {
|
||||||
|
this.messagesEnd = el;
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
</Paper>
|
</Paper>
|
||||||
<form noValidate onSubmit={this.onButtonClicked}>
|
<form noValidate onSubmit={this.onButtonClicked}>
|
||||||
<Grid alignItems="stretch" style={{ display: "flex" }}>
|
<Grid alignItems='stretch' style={{ display: 'flex' }}>
|
||||||
<Grid item alignItems="stretch" style={{ display: "flex"}}>
|
<Grid item alignItems='stretch' style={{ display: 'flex' }}>
|
||||||
<TextField
|
<TextField
|
||||||
label={t("Type a message")}
|
label={t('Type a message')}
|
||||||
variant="standard"
|
variant='standard'
|
||||||
size="small"
|
size='small'
|
||||||
helperText={this.state.connected ? (this.state.peer_pub_key ? null : t("Waiting for peer public key...")) : t("Connecting...")}
|
helperText={
|
||||||
|
this.state.connected
|
||||||
|
? this.state.peer_pub_key
|
||||||
|
? null
|
||||||
|
: t('Waiting for peer public key...')
|
||||||
|
: t('Connecting...')
|
||||||
|
}
|
||||||
value={this.state.value}
|
value={this.state.value}
|
||||||
onChange={e => {
|
onChange={(e) => {
|
||||||
this.setState({ value: e.target.value });
|
this.setState({ value: e.target.value });
|
||||||
this.value = this.state.value;
|
this.value = this.state.value;
|
||||||
}}
|
}}
|
||||||
sx={{width: 219}}
|
sx={{ width: 219 }}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item alignItems="stretch" style={{ display: "flex" }}>
|
<Grid item alignItems='stretch' style={{ display: 'flex' }}>
|
||||||
<Button sx={{'width':68}} disabled={!this.state.connected || this.state.waitingEcho || this.state.peer_pub_key == null} type="submit" variant="contained" color="primary">
|
<Button
|
||||||
{this.state.waitingEcho ?
|
sx={{ width: 68 }}
|
||||||
<div style={{display:'flex',alignItems:'center', flexWrap:'wrap', minWidth:68, width:68, position:"relative",left:15}}>
|
disabled={
|
||||||
<div style={{width:20}}><KeyIcon sx={{width:18}}/></div>
|
!this.state.connected ||
|
||||||
<div style={{width:18}}><CircularProgress size={16} thickness={5}/></div>
|
this.state.waitingEcho ||
|
||||||
|
this.state.peer_pub_key == null
|
||||||
|
}
|
||||||
|
type='submit'
|
||||||
|
variant='contained'
|
||||||
|
color='primary'
|
||||||
|
>
|
||||||
|
{this.state.waitingEcho ? (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
minWidth: 68,
|
||||||
|
width: 68,
|
||||||
|
position: 'relative',
|
||||||
|
left: 15,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{ width: 20 }}>
|
||||||
|
<KeyIcon sx={{ width: 18 }} />
|
||||||
|
</div>
|
||||||
|
<div style={{ width: 18 }}>
|
||||||
|
<CircularProgress size={16} thickness={5} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
:
|
) : (
|
||||||
t("Send")
|
t('Send')
|
||||||
}
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{height:4}}/>
|
<div style={{ height: 4 }} />
|
||||||
|
|
||||||
<Grid container spacing={0}>
|
<Grid container spacing={0}>
|
||||||
<AuditPGPDialog
|
<AuditPGPDialog
|
||||||
open={this.state.audit}
|
open={this.state.audit}
|
||||||
onClose={() => this.setState({audit:false})}
|
onClose={() => this.setState({ audit: false })}
|
||||||
orderId={Number(this.props.orderId)}
|
orderId={Number(this.props.orderId)}
|
||||||
messages={this.state.messages}
|
messages={this.state.messages}
|
||||||
own_pub_key={this.state.own_pub_key}
|
own_pub_key={this.state.own_pub_key}
|
||||||
own_enc_priv_key={this.state.own_enc_priv_key}
|
own_enc_priv_key={this.state.own_enc_priv_key}
|
||||||
peer_pub_key={this.state.peer_pub_key ? this.state.peer_pub_key : "Not received yet"}
|
peer_pub_key={this.state.peer_pub_key ? this.state.peer_pub_key : 'Not received yet'}
|
||||||
passphrase={this.state.token}
|
passphrase={this.state.token}
|
||||||
onClickBack={() => this.setState({audit:false})}
|
onClickBack={() => this.setState({ audit: false })}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Tooltip placement="bottom" enterTouchDelay={0} enterDelay={500} enterNextDelay={2000} title={t("Verify your privacy")}>
|
<Tooltip
|
||||||
<Button size="small" color="primary" variant="outlined" onClick={()=>this.setState({audit:!this.state.audit})}><KeyIcon/>{t("Audit PGP")} </Button>
|
placement='bottom'
|
||||||
|
enterTouchDelay={0}
|
||||||
|
enterDelay={500}
|
||||||
|
enterNextDelay={2000}
|
||||||
|
title={t('Verify your privacy')}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
size='small'
|
||||||
|
color='primary'
|
||||||
|
variant='outlined'
|
||||||
|
onClick={() => this.setState({ audit: !this.state.audit })}
|
||||||
|
>
|
||||||
|
<KeyIcon />
|
||||||
|
{t('Audit PGP')}{' '}
|
||||||
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Tooltip placement="bottom" enterTouchDelay={0} enterDelay={500} enterNextDelay={2000} title={t("Save full log as a JSON file (messages and credentials)")}>
|
<Tooltip
|
||||||
<Button size="small" color="primary" variant="outlined" onClick={()=>saveAsJson('complete_log_chat_'+this.props.orderId+'.json', this.createJsonFile())}><div style={{width:28,height:20}}><ExportIcon sx={{width:20,height:20}}/></div> {t("Export")} </Button>
|
placement='bottom'
|
||||||
|
enterTouchDelay={0}
|
||||||
|
enterDelay={500}
|
||||||
|
enterNextDelay={2000}
|
||||||
|
title={t('Save full log as a JSON file (messages and credentials)')}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
size='small'
|
||||||
|
color='primary'
|
||||||
|
variant='outlined'
|
||||||
|
onClick={() =>
|
||||||
|
saveAsJson(
|
||||||
|
'complete_log_chat_' + this.props.orderId + '.json',
|
||||||
|
this.createJsonFile(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div style={{ width: 28, height: 20 }}>
|
||||||
|
<ExportIcon sx={{ width: 20, height: 20 }} />
|
||||||
|
</div>{' '}
|
||||||
|
{t('Export')}{' '}
|
||||||
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
</Container>
|
</Container>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import React from "react";
|
import React from 'react';
|
||||||
import Flags from 'country-flag-icons/react/3x2'
|
import Flags from 'country-flag-icons/react/3x2';
|
||||||
import SwapCallsIcon from '@mui/icons-material/SwapCalls';
|
import SwapCallsIcon from '@mui/icons-material/SwapCalls';
|
||||||
import { GoldIcon, EarthIcon } from "../Icons";
|
import { GoldIcon, EarthIcon } from '../Icons';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
code: string;
|
code: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
const FlagWithProps = ({ code }: Props): JSX.Element => {
|
const FlagWithProps = ({ code }: Props): JSX.Element => {
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
@ -15,82 +15,80 @@ const FlagWithProps = ({ code }: Props): JSX.Element => {
|
|||||||
|
|
||||||
let flag: JSX.Element | null = null;
|
let flag: JSX.Element | null = null;
|
||||||
|
|
||||||
if(code === 'AED') flag = <Flags.AE {...defaultProps}/>;
|
if (code === 'AED') flag = <Flags.AE {...defaultProps} />;
|
||||||
if(code === 'AUD') flag = <Flags.AU {...defaultProps}/>;
|
if (code === 'AUD') flag = <Flags.AU {...defaultProps} />;
|
||||||
if(code === 'ARS') flag = <Flags.AR {...defaultProps}/>;
|
if (code === 'ARS') flag = <Flags.AR {...defaultProps} />;
|
||||||
if(code === 'BRL') flag = <Flags.BR {...defaultProps}/>;
|
if (code === 'BRL') flag = <Flags.BR {...defaultProps} />;
|
||||||
if(code === 'BYN') flag = <Flags.BY {...defaultProps}/>;
|
if (code === 'BYN') flag = <Flags.BY {...defaultProps} />;
|
||||||
if(code === 'CAD') flag = <Flags.CA {...defaultProps}/>;
|
if (code === 'CAD') flag = <Flags.CA {...defaultProps} />;
|
||||||
if(code === 'CHF') flag = <Flags.CH {...defaultProps}/>;
|
if (code === 'CHF') flag = <Flags.CH {...defaultProps} />;
|
||||||
if(code === 'CLP') flag = <Flags.CL {...defaultProps}/>;
|
if (code === 'CLP') flag = <Flags.CL {...defaultProps} />;
|
||||||
if(code === 'CNY') flag = <Flags.CN {...defaultProps}/>;
|
if (code === 'CNY') flag = <Flags.CN {...defaultProps} />;
|
||||||
if(code === 'EGP') flag = <Flags.EG {...defaultProps}/>;
|
if (code === 'EGP') flag = <Flags.EG {...defaultProps} />;
|
||||||
if(code === 'EUR') flag = <Flags.EU {...defaultProps}/>;
|
if (code === 'EUR') flag = <Flags.EU {...defaultProps} />;
|
||||||
if(code === 'HRK') flag = <Flags.HR {...defaultProps}/>;
|
if (code === 'HRK') flag = <Flags.HR {...defaultProps} />;
|
||||||
if(code === 'CZK') flag = <Flags.CZ {...defaultProps}/>;
|
if (code === 'CZK') flag = <Flags.CZ {...defaultProps} />;
|
||||||
if(code === 'DKK') flag = <Flags.DK {...defaultProps}/>;
|
if (code === 'DKK') flag = <Flags.DK {...defaultProps} />;
|
||||||
if(code === 'GBP') flag = <Flags.GB {...defaultProps}/>;
|
if (code === 'GBP') flag = <Flags.GB {...defaultProps} />;
|
||||||
if(code === 'HKD') flag = <Flags.HK {...defaultProps}/>;
|
if (code === 'HKD') flag = <Flags.HK {...defaultProps} />;
|
||||||
if(code === 'HUF') flag = <Flags.HU {...defaultProps}/>;
|
if (code === 'HUF') flag = <Flags.HU {...defaultProps} />;
|
||||||
if(code === 'INR') flag = <Flags.IN {...defaultProps}/>;
|
if (code === 'INR') flag = <Flags.IN {...defaultProps} />;
|
||||||
if(code === 'ISK') flag = <Flags.IS {...defaultProps}/>;
|
if (code === 'ISK') flag = <Flags.IS {...defaultProps} />;
|
||||||
if(code === 'JPY') flag = <Flags.JP {...defaultProps}/>;
|
if (code === 'JPY') flag = <Flags.JP {...defaultProps} />;
|
||||||
if(code === 'KRW') flag = <Flags.KR {...defaultProps}/>;
|
if (code === 'KRW') flag = <Flags.KR {...defaultProps} />;
|
||||||
if(code === 'LKR') flag = <Flags.LK {...defaultProps}/>;
|
if (code === 'LKR') flag = <Flags.LK {...defaultProps} />;
|
||||||
if(code === 'MAD') flag = <Flags.MA {...defaultProps}/>;
|
if (code === 'MAD') flag = <Flags.MA {...defaultProps} />;
|
||||||
if(code === 'MXN') flag = <Flags.MX {...defaultProps}/>;
|
if (code === 'MXN') flag = <Flags.MX {...defaultProps} />;
|
||||||
if(code === 'NOK') flag = <Flags.NO {...defaultProps}/>;
|
if (code === 'NOK') flag = <Flags.NO {...defaultProps} />;
|
||||||
if(code === 'NZD') flag = <Flags.NZ {...defaultProps}/>;
|
if (code === 'NZD') flag = <Flags.NZ {...defaultProps} />;
|
||||||
if(code === 'PLN') flag = <Flags.PL {...defaultProps}/>;
|
if (code === 'PLN') flag = <Flags.PL {...defaultProps} />;
|
||||||
if(code === 'RON') flag = <Flags.RO {...defaultProps}/>;
|
if (code === 'RON') flag = <Flags.RO {...defaultProps} />;
|
||||||
if(code === 'RUB') flag = <Flags.RU {...defaultProps}/>;
|
if (code === 'RUB') flag = <Flags.RU {...defaultProps} />;
|
||||||
if(code === 'SEK') flag = <Flags.SE {...defaultProps}/>;
|
if (code === 'SEK') flag = <Flags.SE {...defaultProps} />;
|
||||||
if(code === 'SGD') flag = <Flags.SG {...defaultProps}/>;
|
if (code === 'SGD') flag = <Flags.SG {...defaultProps} />;
|
||||||
if(code === 'VES') flag = <Flags.VE {...defaultProps}/>;
|
if (code === 'VES') flag = <Flags.VE {...defaultProps} />;
|
||||||
if(code === 'TRY') flag = <Flags.TR {...defaultProps}/>;
|
if (code === 'TRY') flag = <Flags.TR {...defaultProps} />;
|
||||||
if(code === 'USD') flag = <Flags.US {...defaultProps}/>;
|
if (code === 'USD') flag = <Flags.US {...defaultProps} />;
|
||||||
if(code === 'ZAR') flag = <Flags.ZA {...defaultProps}/>;
|
if (code === 'ZAR') flag = <Flags.ZA {...defaultProps} />;
|
||||||
if(code === 'COP') flag = <Flags.CO {...defaultProps}/>;
|
if (code === 'COP') flag = <Flags.CO {...defaultProps} />;
|
||||||
if(code === 'PEN') flag = <Flags.PE {...defaultProps}/>;
|
if (code === 'PEN') flag = <Flags.PE {...defaultProps} />;
|
||||||
if(code === 'UYU') flag = <Flags.UY {...defaultProps}/>;
|
if (code === 'UYU') flag = <Flags.UY {...defaultProps} />;
|
||||||
if(code === 'PYG') flag = <Flags.PY {...defaultProps}/>;
|
if (code === 'PYG') flag = <Flags.PY {...defaultProps} />;
|
||||||
if(code === 'BOB') flag = <Flags.BO {...defaultProps}/>;
|
if (code === 'BOB') flag = <Flags.BO {...defaultProps} />;
|
||||||
if(code === 'IDR') flag = <Flags.ID {...defaultProps}/>;
|
if (code === 'IDR') flag = <Flags.ID {...defaultProps} />;
|
||||||
if(code === 'ANG') flag = <Flags.CW {...defaultProps}/>;
|
if (code === 'ANG') flag = <Flags.CW {...defaultProps} />;
|
||||||
if(code === 'CRC') flag = <Flags.CR {...defaultProps}/>;
|
if (code === 'CRC') flag = <Flags.CR {...defaultProps} />;
|
||||||
if(code === 'CUP') flag = <Flags.CU {...defaultProps}/>;
|
if (code === 'CUP') flag = <Flags.CU {...defaultProps} />;
|
||||||
if(code === 'DOP') flag = <Flags.DO {...defaultProps}/>;
|
if (code === 'DOP') flag = <Flags.DO {...defaultProps} />;
|
||||||
if(code === 'GHS') flag = <Flags.GH {...defaultProps}/>;
|
if (code === 'GHS') flag = <Flags.GH {...defaultProps} />;
|
||||||
if(code === 'GTQ') flag = <Flags.GT {...defaultProps}/>;
|
if (code === 'GTQ') flag = <Flags.GT {...defaultProps} />;
|
||||||
if(code === 'ILS') flag = <Flags.IL {...defaultProps}/>;
|
if (code === 'ILS') flag = <Flags.IL {...defaultProps} />;
|
||||||
if(code === 'JMD') flag = <Flags.JM {...defaultProps}/>;
|
if (code === 'JMD') flag = <Flags.JM {...defaultProps} />;
|
||||||
if(code === 'KES') flag = <Flags.KE {...defaultProps}/>;
|
if (code === 'KES') flag = <Flags.KE {...defaultProps} />;
|
||||||
if(code === 'KZT') flag = <Flags.KZ {...defaultProps}/>;
|
if (code === 'KZT') flag = <Flags.KZ {...defaultProps} />;
|
||||||
if(code === 'MYR') flag = <Flags.MY {...defaultProps}/>;
|
if (code === 'MYR') flag = <Flags.MY {...defaultProps} />;
|
||||||
if(code === 'NAD') flag = <Flags.NA {...defaultProps}/>;
|
if (code === 'NAD') flag = <Flags.NA {...defaultProps} />;
|
||||||
if(code === 'NGN') flag = <Flags.NG {...defaultProps}/>;
|
if (code === 'NGN') flag = <Flags.NG {...defaultProps} />;
|
||||||
if(code === 'AZN') flag = <Flags.AZ {...defaultProps}/>;
|
if (code === 'AZN') flag = <Flags.AZ {...defaultProps} />;
|
||||||
if(code === 'PAB') flag = <Flags.PA {...defaultProps}/>;
|
if (code === 'PAB') flag = <Flags.PA {...defaultProps} />;
|
||||||
if(code === 'PHP') flag = <Flags.PH {...defaultProps}/>;
|
if (code === 'PHP') flag = <Flags.PH {...defaultProps} />;
|
||||||
if(code === 'PKR') flag = <Flags.PK {...defaultProps}/>;
|
if (code === 'PKR') flag = <Flags.PK {...defaultProps} />;
|
||||||
if(code === 'QAR') flag = <Flags.QA {...defaultProps}/>;
|
if (code === 'QAR') flag = <Flags.QA {...defaultProps} />;
|
||||||
if(code === 'SAR') flag = <Flags.SA {...defaultProps}/>;
|
if (code === 'SAR') flag = <Flags.SA {...defaultProps} />;
|
||||||
if(code === 'THB') flag = <Flags.TH {...defaultProps}/>;
|
if (code === 'THB') flag = <Flags.TH {...defaultProps} />;
|
||||||
if(code === 'TTD') flag = <Flags.TT {...defaultProps}/>;
|
if (code === 'TTD') flag = <Flags.TT {...defaultProps} />;
|
||||||
if(code === 'VND') flag = <Flags.VN {...defaultProps}/>;
|
if (code === 'VND') flag = <Flags.VN {...defaultProps} />;
|
||||||
if(code === 'XOF') flag = <Flags.BJ {...defaultProps}/>;
|
if (code === 'XOF') flag = <Flags.BJ {...defaultProps} />;
|
||||||
if(code === 'TWD') flag = <Flags.TW {...defaultProps}/>;
|
if (code === 'TWD') flag = <Flags.TW {...defaultProps} />;
|
||||||
if(code === 'TZS') flag = <Flags.TZ {...defaultProps}/>;
|
if (code === 'TZS') flag = <Flags.TZ {...defaultProps} />;
|
||||||
if(code === 'XAF') flag = <Flags.CM {...defaultProps}/>;
|
if (code === 'XAF') flag = <Flags.CM {...defaultProps} />;
|
||||||
if(code === 'UAH') flag = <Flags.UA {...defaultProps}/>;
|
if (code === 'UAH') flag = <Flags.UA {...defaultProps} />;
|
||||||
if(code === 'TND') flag = <Flags.TN {...defaultProps}/>;
|
if (code === 'TND') flag = <Flags.TN {...defaultProps} />;
|
||||||
if(code === 'ANY') flag = <EarthIcon {...defaultProps}/>;
|
if (code === 'ANY') flag = <EarthIcon {...defaultProps} />;
|
||||||
if(code === 'XAU') flag = <GoldIcon {...defaultProps}/>;
|
if (code === 'XAU') flag = <GoldIcon {...defaultProps} />;
|
||||||
if(code === 'BTC') flag = <SwapCallsIcon color="primary"/>;
|
if (code === 'BTC') flag = <SwapCallsIcon color='primary' />;
|
||||||
|
|
||||||
return (
|
return <div style={{ width: 28, height: 20 }}>{flag}</div>;
|
||||||
<div style={{width:28, height: 20}}>{flag}</div>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FlagWithProps;
|
export default FlagWithProps;
|
||||||
|
@ -1 +1 @@
|
|||||||
export { default } from "./FlagWithProps";
|
export { default } from './FlagWithProps';
|
||||||
|
@ -1,62 +1,128 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import { BrowserRouter as Router, Switch, Route, Link, Redirect,useHistory } from "react-router-dom";
|
import {
|
||||||
|
BrowserRouter as Router,
|
||||||
|
Switch,
|
||||||
|
Route,
|
||||||
|
Link,
|
||||||
|
Redirect,
|
||||||
|
useHistory,
|
||||||
|
} from 'react-router-dom';
|
||||||
|
|
||||||
import UserGenPage from "./UserGenPage";
|
import UserGenPage from './UserGenPage';
|
||||||
import MakerPage from "./MakerPage";
|
import MakerPage from './MakerPage';
|
||||||
import BookPage from "./BookPage";
|
import BookPage from './BookPage';
|
||||||
import OrderPage from "./OrderPage";
|
import OrderPage from './OrderPage';
|
||||||
import BottomBar from "./BottomBar";
|
import BottomBar from './BottomBar';
|
||||||
|
|
||||||
export default class HomePage extends Component {
|
export default class HomePage extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
nickname: null,
|
nickname: null,
|
||||||
token: null,
|
token: null,
|
||||||
copiedToken: false,
|
copiedToken: false,
|
||||||
avatarLoaded: false,
|
avatarLoaded: false,
|
||||||
buyChecked: false,
|
buyChecked: false,
|
||||||
sellChecked: false,
|
sellChecked: false,
|
||||||
type:2,
|
type: 2,
|
||||||
currency:0,
|
currency: 0,
|
||||||
bookCurrencyCode:'ANY',
|
bookCurrencyCode: 'ANY',
|
||||||
bookOrders:new Array(),
|
bookOrders: new Array(),
|
||||||
bookLoading: true,
|
bookLoading: true,
|
||||||
activeOrderId: null,
|
activeOrderId: null,
|
||||||
lastOrderId: null,
|
lastOrderId: null,
|
||||||
earnedRewards: 0,
|
earnedRewards: 0,
|
||||||
referralCode:'',
|
referralCode: '',
|
||||||
lastDayPremium: 0,
|
lastDayPremium: 0,
|
||||||
limits: {}
|
limits: {},
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
setAppState=(newState)=>{
|
setAppState = (newState) => {
|
||||||
this.setState(newState)
|
this.setState(newState);
|
||||||
}
|
};
|
||||||
|
|
||||||
redirectTo(location) {
|
redirectTo(location) {
|
||||||
this.props.history.push(location);
|
this.props.history.push(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const fontSize = this.props.theme.typography.fontSize;
|
const fontSize = this.props.theme.typography.fontSize;
|
||||||
const fontSizeFactor = fontSize / 14; // default fontSize is 14
|
const fontSizeFactor = fontSize / 14; // default fontSize is 14
|
||||||
return (
|
return (
|
||||||
<Router >
|
<Router>
|
||||||
<div className='appCenter'>
|
<div className='appCenter'>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path='/' render={(props) => <UserGenPage {...props} {...this.state} {...this.props} setAppState={this.setAppState}/>}/>
|
<Route
|
||||||
<Route path='/ref/:refCode' render={(props) => <UserGenPage {...props} {...this.state} {...this.props} setAppState={this.setAppState}/>}/>
|
exact
|
||||||
<Route path='/make' render={(props) => <MakerPage {...props} {...this.state} {...this.props} setAppState={this.setAppState}/>}/>
|
path='/'
|
||||||
<Route path='/book' render={(props) => <BookPage {...props} {...this.state} {...this.props} setAppState={this.setAppState} />}/>
|
render={(props) => (
|
||||||
<Route path="/order/:orderId" render={(props) => <OrderPage {...props} {...this.state} {...this.props} setAppState={this.setAppState}/>}/>
|
<UserGenPage
|
||||||
</Switch>
|
{...props}
|
||||||
</div>
|
{...this.state}
|
||||||
<div className='bottomBar' style={{height: `${40*fontSizeFactor}px`, width: window.innerWidth}}>
|
{...this.props}
|
||||||
<BottomBar redirectTo={this.redirectTo} {...this.state} {...this.props} setAppState={this.setAppState} />
|
setAppState={this.setAppState}
|
||||||
</div>
|
/>
|
||||||
</Router>
|
)}
|
||||||
);
|
/>
|
||||||
}
|
<Route
|
||||||
|
path='/ref/:refCode'
|
||||||
|
render={(props) => (
|
||||||
|
<UserGenPage
|
||||||
|
{...props}
|
||||||
|
{...this.state}
|
||||||
|
{...this.props}
|
||||||
|
setAppState={this.setAppState}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path='/make'
|
||||||
|
render={(props) => (
|
||||||
|
<MakerPage
|
||||||
|
{...props}
|
||||||
|
{...this.state}
|
||||||
|
{...this.props}
|
||||||
|
setAppState={this.setAppState}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path='/book'
|
||||||
|
render={(props) => (
|
||||||
|
<BookPage
|
||||||
|
{...props}
|
||||||
|
{...this.state}
|
||||||
|
{...this.props}
|
||||||
|
setAppState={this.setAppState}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path='/order/:orderId'
|
||||||
|
render={(props) => (
|
||||||
|
<OrderPage
|
||||||
|
{...props}
|
||||||
|
{...this.state}
|
||||||
|
{...this.props}
|
||||||
|
setAppState={this.setAppState}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Switch>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='bottomBar'
|
||||||
|
style={{ height: `${40 * fontSizeFactor}px`, width: window.innerWidth }}
|
||||||
|
>
|
||||||
|
<BottomBar
|
||||||
|
redirectTo={this.redirectTo}
|
||||||
|
{...this.state}
|
||||||
|
{...this.props}
|
||||||
|
setAppState={this.setAppState}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Router>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,28 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import { SvgIcon } from "@mui/material"
|
import { SvgIcon } from '@mui/material';
|
||||||
|
|
||||||
export default function AmbossIcon(props) {
|
export default function AmbossIcon(props) {
|
||||||
return (
|
return (
|
||||||
<SvgIcon {...props} x="0px" y="0px" viewBox="0 0 95.7 84.9">
|
<SvgIcon {...props} x='0px' y='0px' viewBox='0 0 95.7 84.9'>
|
||||||
<g id="Layer_2_00000052094167160547307180000012226084410257483709_">
|
<g id='Layer_2_00000052094167160547307180000012226084410257483709_'>
|
||||||
<g id="Layer_1-2">
|
<g id='Layer_1-2'>
|
||||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="0" y1="42.45" x2="95.7" y2="42.45">
|
<linearGradient
|
||||||
<stop offset="0" style={{stopColor:'#925bc9'}}/>
|
id='SVGID_1_'
|
||||||
<stop offset="1" style={{stopColor:'#ff59ac'}}/>
|
gradientUnits='userSpaceOnUse'
|
||||||
</linearGradient>
|
x1='0'
|
||||||
<path className={"amboss"} d="M55.3,84.9V61.3h-15v23.6H0V0h95.7v84.9H55.3z M55.3,28.1h-15v17.1h15V28.1z"/>
|
y1='42.45'
|
||||||
</g>
|
x2='95.7'
|
||||||
|
y2='42.45'
|
||||||
|
>
|
||||||
|
<stop offset='0' style={{ stopColor: '#925bc9' }} />
|
||||||
|
<stop offset='1' style={{ stopColor: '#ff59ac' }} />
|
||||||
|
</linearGradient>
|
||||||
|
<path
|
||||||
|
className={'amboss'}
|
||||||
|
d='M55.3,84.9V61.3h-15v23.6H0V0h95.7v84.9H55.3z M55.3,28.1h-15v17.1h15V28.1z'
|
||||||
|
/>
|
||||||
</g>
|
</g>
|
||||||
</SvgIcon>
|
</g>
|
||||||
);
|
</SvgIcon>
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import { SvgIcon } from "@mui/material"
|
import { SvgIcon } from '@mui/material';
|
||||||
|
|
||||||
export default function BasqueCountryFlag(props) {
|
export default function BasqueCountryFlag(props) {
|
||||||
return (
|
return (
|
||||||
<SvgIcon {...props} x="0px" y="0px" viewBox="0 0 50 28">
|
<SvgIcon {...props} x='0px' y='0px' viewBox='0 0 50 28'>
|
||||||
<path d="M0,0 v28 h50 v-28 z" fill="#D52B1E"/>
|
<path d='M0,0 v28 h50 v-28 z' fill='#D52B1E' />
|
||||||
<path d="M0,0 L50,28 M50,0 L0,28" stroke="#009B48" strokeWidth="4.3"/>
|
<path d='M0,0 L50,28 M50,0 L0,28' stroke='#009B48' strokeWidth='4.3' />
|
||||||
<path d="M25,0 v28 M0,14 h50" stroke="#fff" strokeWidth="4.3"/>
|
<path d='M25,0 v28 M0,14 h50' stroke='#fff' strokeWidth='4.3' />
|
||||||
</SvgIcon>
|
</SvgIcon>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import { SvgIcon } from "@mui/material"
|
import { SvgIcon } from '@mui/material';
|
||||||
|
|
||||||
export default function BitcoinIcon(props) {
|
export default function BitcoinIcon(props) {
|
||||||
return (
|
return (
|
||||||
<SvgIcon sx={props.sx} color={props.color} viewBox="0 0 512 512">
|
<SvgIcon sx={props.sx} color={props.color} viewBox='0 0 512 512'>
|
||||||
<path d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-141.651-35.33c4.937-32.999-20.191-50.739-54.55-62.573l11.146-44.702-27.213-6.781-10.851 43.524c-7.154-1.783-14.502-3.464-21.803-5.13l10.929-43.81-27.198-6.781-11.153 44.686c-5.922-1.349-11.735-2.682-17.377-4.084l.031-.14-37.53-9.37-7.239 29.062s20.191 4.627 19.765 4.913c11.022 2.751 13.014 10.044 12.68 15.825l-12.696 50.925c.76.194 1.744.473 2.829.907-.907-.225-1.876-.473-2.876-.713l-17.796 71.338c-1.349 3.348-4.767 8.37-12.471 6.464.271.395-19.78-4.937-19.78-4.937l-13.51 31.147 35.414 8.827c6.588 1.651 13.045 3.379 19.4 5.006l-11.262 45.213 27.182 6.781 11.153-44.733a1038.209 1038.209 0 0 0 21.687 5.627l-11.115 44.523 27.213 6.781 11.262-45.128c46.404 8.781 81.299 5.239 95.986-36.727 11.836-33.79-.589-53.281-25.004-65.991 17.78-4.098 31.174-15.792 34.747-39.949zm-62.177 87.179c-8.41 33.79-65.308 15.523-83.755 10.943l14.944-59.899c18.446 4.603 77.6 13.717 68.811 48.956zm8.417-87.667c-7.673 30.736-55.031 15.12-70.393 11.292l13.548-54.327c15.363 3.828 64.836 10.973 56.845 43.035z"/>
|
<path d='M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-141.651-35.33c4.937-32.999-20.191-50.739-54.55-62.573l11.146-44.702-27.213-6.781-10.851 43.524c-7.154-1.783-14.502-3.464-21.803-5.13l10.929-43.81-27.198-6.781-11.153 44.686c-5.922-1.349-11.735-2.682-17.377-4.084l.031-.14-37.53-9.37-7.239 29.062s20.191 4.627 19.765 4.913c11.022 2.751 13.014 10.044 12.68 15.825l-12.696 50.925c.76.194 1.744.473 2.829.907-.907-.225-1.876-.473-2.876-.713l-17.796 71.338c-1.349 3.348-4.767 8.37-12.471 6.464.271.395-19.78-4.937-19.78-4.937l-13.51 31.147 35.414 8.827c6.588 1.651 13.045 3.379 19.4 5.006l-11.262 45.213 27.182 6.781 11.153-44.733a1038.209 1038.209 0 0 0 21.687 5.627l-11.115 44.523 27.213 6.781 11.262-45.128c46.404 8.781 81.299 5.239 95.986-36.727 11.836-33.79-.589-53.281-25.004-65.991 17.78-4.098 31.174-15.792 34.747-39.949zm-62.177 87.179c-8.41 33.79-65.308 15.523-83.755 10.943l14.944-59.899c18.446 4.603 77.6 13.717 68.811 48.956zm8.417-87.667c-7.673 30.736-55.031 15.12-70.393 11.292l13.548-54.327c15.363 3.828 64.836 10.973 56.845 43.035z' />
|
||||||
</SvgIcon>
|
</SvgIcon>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import { SvgIcon } from "@mui/material"
|
import { SvgIcon } from '@mui/material';
|
||||||
|
|
||||||
export default function BitcoinSignIcon(props) {
|
export default function BitcoinSignIcon(props) {
|
||||||
return (
|
return (
|
||||||
<SvgIcon sx={props.sx} color={props.color} viewBox="0 0 320 512">
|
<SvgIcon sx={props.sx} color={props.color} viewBox='0 0 320 512'>
|
||||||
<path d="M48 32C48 14.33 62.33 0 80 0C97.67 0 112 14.33 112 32V64H144V32C144 14.33 158.3 0 176 0C193.7 0 208 14.33 208 32V64C208 65.54 207.9 67.06 207.7 68.54C254.1 82.21 288 125.1 288 176C288 200.2 280.3 222.6 267.3 240.9C298.9 260.7 320 295.9 320 336C320 397.9 269.9 448 208 448V480C208 497.7 193.7 512 176 512C158.3 512 144 497.7 144 480V448H112V480C112 497.7 97.67 512 80 512C62.33 512 48 497.7 48 480V448H41.74C18.69 448 0 429.3 0 406.3V101.6C0 80.82 16.82 64 37.57 64H48V32zM176 224C202.5 224 224 202.5 224 176C224 149.5 202.5 128 176 128H64V224H176zM64 288V384H208C234.5 384 256 362.5 256 336C256 309.5 234.5 288 208 288H64z"/>
|
<path d='M48 32C48 14.33 62.33 0 80 0C97.67 0 112 14.33 112 32V64H144V32C144 14.33 158.3 0 176 0C193.7 0 208 14.33 208 32V64C208 65.54 207.9 67.06 207.7 68.54C254.1 82.21 288 125.1 288 176C288 200.2 280.3 222.6 267.3 240.9C298.9 260.7 320 295.9 320 336C320 397.9 269.9 448 208 448V480C208 497.7 193.7 512 176 512C158.3 512 144 497.7 144 480V448H112V480C112 497.7 97.67 512 80 512C62.33 512 48 497.7 48 480V448H41.74C18.69 448 0 429.3 0 406.3V101.6C0 80.82 16.82 64 37.57 64H48V32zM176 224C202.5 224 224 202.5 224 176C224 149.5 202.5 128 176 128H64V224H176zM64 288V384H208C234.5 384 256 362.5 256 336C256 309.5 234.5 288 208 288H64z' />
|
||||||
</SvgIcon>
|
</SvgIcon>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,49 +1,111 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import { SvgIcon } from "@mui/material"
|
import { SvgIcon } from '@mui/material';
|
||||||
|
|
||||||
export default function BuySatsIcon(props) {
|
export default function BuySatsIcon(props) {
|
||||||
return (
|
return (
|
||||||
<SvgIcon sx={props.sx} color={props.color} x="0px" y="0px" viewBox="0 0 300 300">
|
<SvgIcon sx={props.sx} color={props.color} x='0px' y='0px' viewBox='0 0 300 300'>
|
||||||
<g>
|
<g>
|
||||||
<polygon fill={props.color} points="178.391,189.96 174.934,186.875 169.489,182.018 166.596,179.436 161.154,174.579 158.645,172.34
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
|
points='178.391,189.96 174.934,186.875 169.489,182.018 166.596,179.436 161.154,174.579 158.645,172.34
|
||||||
157.717,171.51 152.893,176.918 155.712,179.436 161.154,184.291 164.049,186.875 169.491,191.73 172.947,194.816
|
157.717,171.51 152.893,176.918 155.712,179.436 161.154,184.291 164.049,186.875 169.491,191.73 172.947,194.816
|
||||||
177.943,199.271 180.826,197.5 184.389,195.311 183.834,194.816 "/>
|
177.943,199.271 180.826,197.5 184.389,195.311 183.834,194.816 '
|
||||||
<polygon fill={props.color} points="166.034,194.816 160.588,189.96 157.695,187.377 152.256,182.521 150.52,180.975 149.592,180.145
|
/>
|
||||||
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
|
points='166.034,194.816 160.588,189.96 157.695,187.377 152.256,182.521 150.52,180.975 149.592,180.145
|
||||||
144.766,185.551 146.813,187.377 152.256,192.232 155.146,194.814 160.59,199.672 164.049,202.756 167.4,205.748 173.85,201.787
|
144.766,185.551 146.813,187.377 152.256,192.232 155.146,194.814 160.59,199.672 164.049,202.756 167.4,205.748 173.85,201.787
|
||||||
169.491,197.9 "/>
|
169.491,197.9 '
|
||||||
<polygon fill={props.color} points="157.695,202.255 152.253,197.398 149.358,194.816 143.916,189.96 142.014,188.26 137.189,193.668
|
/>
|
||||||
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
|
points='157.695,202.255 152.253,197.398 149.358,194.816 143.916,189.96 142.014,188.26 137.189,193.668
|
||||||
138.476,194.816 143.92,199.672 146.813,202.254 152.256,207.109 155.712,210.195 157.527,211.816 163.973,207.854
|
138.476,194.816 143.92,199.672 146.813,202.254 152.256,207.109 155.712,210.195 157.527,211.816 163.973,207.854
|
||||||
161.154,205.34 "/>
|
161.154,205.34 '
|
||||||
|
/>
|
||||||
<rect x="173.431" y="172.686" transform="matrix(0.7405 0.672 -0.672 0.7405 165.1439 -72.7109)" fill={props.color} width="6.611" height="9.654"/>
|
|
||||||
<polygon fill={props.color} points="141.129,211.877 147.035,215.203 150.877,210.975 145.981,206.533 "/>
|
<rect
|
||||||
<polygon fill={props.color} points="186.961,57.038 189.855,59.621 195.298,64.477 198.756,67.562 204.199,72.418 205.449,73.534
|
x='173.431'
|
||||||
|
y='172.686'
|
||||||
|
transform='matrix(0.7405 0.672 -0.672 0.7405 165.1439 -72.7109)'
|
||||||
|
fill={props.color}
|
||||||
|
width='6.611'
|
||||||
|
height='9.654'
|
||||||
|
/>
|
||||||
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
|
points='141.129,211.877 147.035,215.203 150.877,210.975 145.981,206.533 '
|
||||||
|
/>
|
||||||
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
|
points='186.961,57.038 189.855,59.621 195.298,64.477 198.756,67.562 204.199,72.418 205.449,73.534
|
||||||
210.271,68.126 209.643,67.562 204.199,62.705 200.742,59.621 195.298,54.764 192.402,52.182 186.963,47.326 184.453,45.086
|
210.271,68.126 209.643,67.562 204.199,62.705 200.742,59.621 195.298,54.764 192.402,52.182 186.963,47.326 184.453,45.086
|
||||||
183.525,44.256 178.695,49.665 181.52,52.182 "/>
|
183.525,44.256 178.695,49.665 181.52,52.182 '
|
||||||
<polygon fill={props.color} points="178.062,64.979 180.954,67.562 186.398,72.418 189.855,75.503 195.298,80.359 196.396,81.34
|
/>
|
||||||
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
|
points='178.062,64.979 180.954,67.562 186.398,72.418 189.855,75.503 195.298,80.359 196.396,81.34
|
||||||
197.325,82.166 202.146,76.76 200.742,75.503 195.298,70.648 191.841,67.562 186.398,62.705 183.505,60.124 178.062,55.268
|
197.325,82.166 202.146,76.76 200.742,75.503 195.298,70.648 191.841,67.562 186.398,62.705 183.505,60.124 178.062,55.268
|
||||||
176.328,53.72 175.396,52.89 170.572,58.299 172.618,60.124 "/>
|
176.328,53.72 175.396,52.89 170.572,58.299 172.618,60.124 '
|
||||||
<polygon fill={props.color} points="169.723,72.418 172.618,75 178.062,79.856 181.52,82.941 186.962,87.798 188.818,89.456
|
/>
|
||||||
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
|
points='169.723,72.418 172.618,75 178.062,79.856 181.52,82.941 186.962,87.798 188.818,89.456
|
||||||
189.747,90.282 194.57,84.875 192.402,82.942 186.962,78.085 183.505,75 178.062,70.144 175.167,67.562 169.723,62.705
|
189.747,90.282 194.57,84.875 192.402,82.942 186.962,78.085 183.505,75 178.062,70.144 175.167,67.562 169.723,62.705
|
||||||
167.82,61.006 162.998,66.415 164.282,67.562 "/>
|
167.82,61.006 162.998,66.415 164.282,67.562 '
|
||||||
|
/>
|
||||||
<rect x="199.243" y="45.425" transform="matrix(0.7403 0.6723 -0.6723 0.7403 86.3919 -123.1221)" fill={props.color} width="6.609" height="9.656"/>
|
|
||||||
<polygon fill={props.color} points="165.298,86.425 170.193,90.867 176.684,83.72 171.789,79.28 "/>
|
<rect
|
||||||
<polygon fill={props.color} points="88.684,102.6 87.755,101.77 82.927,107.177 105.743,127.533 109.679,131.046 114.503,125.64
|
x='199.243'
|
||||||
112.599,123.938 "/>
|
y='45.425'
|
||||||
<polygon fill={props.color} points="80.557,111.232 79.631,110.403 74.803,115.811 94.669,133.537 100.627,138.853 101.553,139.68
|
transform='matrix(0.7403 0.6723 -0.6723 0.7403 86.3919 -123.1221)'
|
||||||
106.378,134.272 101.42,129.848 "/>
|
fill={props.color}
|
||||||
<polygon fill={props.color} points="72.049,118.52 67.228,123.928 84.469,139.311 92.184,146.195 93.051,146.968 93.978,147.795
|
width='6.609'
|
||||||
98.659,142.548 98.802,142.389 91.107,135.525 "/>
|
height='9.656'
|
||||||
|
/>
|
||||||
<rect x="103.471" y="102.94" transform="matrix(0.7405 0.6721 -0.6721 0.7405 100.1373 -43.7934)" fill={props.color} width="6.609" height="9.654"/>
|
<polygon
|
||||||
<polygon fill={props.color} points="69.529,143.938 72.38,146.525 74.422,148.381 80.622,141.554 80.914,141.234 76.019,136.792 "/>
|
fill={props.color}
|
||||||
<path fill={props.color} d="M187.466,112.718c7.511,0,14.995-1.878,21.647-5.43c10.848-5.793,18.796-15.48,22.379-27.277
|
points='165.298,86.425 170.193,90.867 176.684,83.72 171.789,79.28 '
|
||||||
|
/>
|
||||||
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
|
points='88.684,102.6 87.755,101.77 82.927,107.177 105.743,127.533 109.679,131.046 114.503,125.64
|
||||||
|
112.599,123.938 '
|
||||||
|
/>
|
||||||
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
|
points='80.557,111.232 79.631,110.403 74.803,115.811 94.669,133.537 100.627,138.853 101.553,139.68
|
||||||
|
106.378,134.272 101.42,129.848 '
|
||||||
|
/>
|
||||||
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
|
points='72.049,118.52 67.228,123.928 84.469,139.311 92.184,146.195 93.051,146.968 93.978,147.795
|
||||||
|
98.659,142.548 98.802,142.389 91.107,135.525 '
|
||||||
|
/>
|
||||||
|
|
||||||
|
<rect
|
||||||
|
x='103.471'
|
||||||
|
y='102.94'
|
||||||
|
transform='matrix(0.7405 0.6721 -0.6721 0.7405 100.1373 -43.7934)'
|
||||||
|
fill={props.color}
|
||||||
|
width='6.609'
|
||||||
|
height='9.654'
|
||||||
|
/>
|
||||||
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
|
points='69.529,143.938 72.38,146.525 74.422,148.381 80.622,141.554 80.914,141.234 76.019,136.792 '
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill={props.color}
|
||||||
|
d='M187.466,112.718c7.511,0,14.995-1.878,21.647-5.43c10.848-5.793,18.796-15.48,22.379-27.277
|
||||||
c3.583-11.796,2.365-24.266-3.426-35.113c-8.033-15.037-23.645-24.379-40.742-24.379c-7.51,0-14.996,1.878-21.648,5.431
|
c3.583-11.796,2.365-24.266-3.426-35.113c-8.033-15.037-23.645-24.379-40.742-24.379c-7.51,0-14.996,1.878-21.648,5.431
|
||||||
c-10.847,5.793-18.794,15.479-22.377,27.275s-2.366,24.266,3.426,35.113C154.755,103.376,170.365,112.718,187.466,112.718z
|
c-10.847,5.793-18.794,15.479-22.377,27.275s-2.366,24.266,3.426,35.113C154.755,103.376,170.365,112.718,187.466,112.718z
|
||||||
M171.232,36.355c16.688-8.912,37.514-2.587,46.43,14.099c8.908,16.688,2.584,37.516-14.104,46.428
|
M171.232,36.355c16.688-8.912,37.514-2.587,46.43,14.099c8.908,16.688,2.584,37.516-14.104,46.428
|
||||||
c-16.688,8.913-37.518,2.586-46.431-14.1C148.219,66.092,154.544,45.268,171.232,36.355z"/>
|
c-16.688,8.913-37.518,2.586-46.431-14.1C148.219,66.092,154.544,45.268,171.232,36.355z'
|
||||||
<path fill={props.color} d="M247.809,155.361c-6.326-5.757-17.865-13.456-34.295-22.881c-18.544-10.639-43.998-23.456-59.836-27.527
|
/>
|
||||||
|
<path
|
||||||
|
fill={props.color}
|
||||||
|
d='M247.809,155.361c-6.326-5.757-17.865-13.456-34.295-22.881c-18.544-10.639-43.998-23.456-59.836-27.527
|
||||||
c-0.785-0.199-1.621-0.3-2.484-0.3c-1.917,0-5.62,0.546-15.812,4.946c-0.823-2.478-1.856-4.885-3.086-7.188
|
c-0.785-0.199-1.621-0.3-2.484-0.3c-1.917,0-5.62,0.546-15.812,4.946c-0.823-2.478-1.856-4.885-3.086-7.188
|
||||||
c-8.032-15.037-23.644-24.379-40.743-24.379c-7.509,0-14.995,1.878-21.646,5.43c-10.847,5.792-18.795,15.478-22.378,27.275
|
c-8.032-15.037-23.644-24.379-40.743-24.379c-7.509,0-14.995,1.878-21.646,5.43c-10.847,5.792-18.795,15.478-22.378,27.275
|
||||||
c-3.583,11.797-2.365,24.267,3.428,35.113c1.488,2.787,3.262,5.414,5.295,7.841c-3.117,2.348-5.28,4.3-6.706,6.043
|
c-3.583,11.797-2.365,24.267,3.428,35.113c1.488,2.787,3.262,5.414,5.295,7.841c-3.117,2.348-5.28,4.3-6.706,6.043
|
||||||
@ -60,12 +122,16 @@ export default function BuySatsIcon(props) {
|
|||||||
c-8.912-16.687-2.588-37.511,14.1-46.422c16.689-8.914,37.516-2.588,46.43,14.101c1.647,3.086,2.772,6.316,3.407,9.585
|
c-8.912-16.687-2.588-37.511,14.1-46.422c16.689-8.914,37.516-2.588,46.43,14.101c1.647,3.086,2.772,6.316,3.407,9.585
|
||||||
C125.997,121.143,126.1,124.779,125.656,128.328z M59.715,174.898l34.511,20.586l-34.511,60.934V174.898z M102.657,200.516
|
C125.997,121.143,126.1,124.779,125.656,128.328z M59.715,174.898l34.511,20.586l-34.511,60.934V174.898z M102.657,200.516
|
||||||
l47.237,28.182l46.69-28.232l37.43,66.088c-0.445,0.067-0.896,0.114-1.358,0.114H68.718c-1.125,0-2.196-0.216-3.19-0.595
|
l47.237,28.182l46.69-28.232l37.43,66.088c-0.445,0.067-0.896,0.114-1.358,0.114H68.718c-1.125,0-2.196-0.216-3.19-0.595
|
||||||
L102.657,200.516z"/>
|
L102.657,200.516z'
|
||||||
<path fill={props.color} d="M269.921,0H30.08C13.493,0,0,13.494,0,30.08v239.84C0,286.506,13.493,300,30.08,300h239.841
|
/>
|
||||||
|
<path
|
||||||
|
fill={props.color}
|
||||||
|
d='M269.921,0H30.08C13.493,0,0,13.494,0,30.08v239.84C0,286.506,13.493,300,30.08,300h239.841
|
||||||
C286.506,300,300,286.506,300,269.92V30.08C300,13.494,286.506,0,269.921,0z M284.413,269.92c0,7.992-6.501,14.494-14.492,14.494
|
C286.506,300,300,286.506,300,269.92V30.08C300,13.494,286.506,0,269.921,0z M284.413,269.92c0,7.992-6.501,14.494-14.492,14.494
|
||||||
H30.08c-7.992,0-14.494-6.502-14.494-14.494V30.08c0-7.992,6.502-14.494,14.494-14.494h239.841
|
H30.08c-7.992,0-14.494-6.502-14.494-14.494V30.08c0-7.992,6.502-14.494,14.494-14.494h239.841
|
||||||
c7.991,0,14.492,6.502,14.492,14.494V269.92z"/>
|
c7.991,0,14.492,6.502,14.492,14.494V269.92z'
|
||||||
</g>
|
/>
|
||||||
</SvgIcon>
|
</g>
|
||||||
);
|
</SvgIcon>
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import { SvgIcon } from "@mui/material"
|
import { SvgIcon } from '@mui/material';
|
||||||
|
|
||||||
export default function BuySatsCheckedIcon(props) {
|
export default function BuySatsCheckedIcon(props) {
|
||||||
return (
|
return (
|
||||||
<SvgIcon sx={props.sx} color={props.color} x="0px" y="0px" viewBox="0 0 300 300">
|
<SvgIcon sx={props.sx} color={props.color} x='0px' y='0px' viewBox='0 0 300 300'>
|
||||||
<g>
|
<g>
|
||||||
<path fill={props.color} d="M269.921,0H30.08C13.493,0,0,13.494,0,30.08v239.84C0,286.506,13.493,300,30.08,300h239.841
|
<path
|
||||||
|
fill={props.color}
|
||||||
|
d='M269.921,0H30.08C13.493,0,0,13.494,0,30.08v239.84C0,286.506,13.493,300,30.08,300h239.841
|
||||||
C286.506,300,300,286.506,300,269.92V30.08C300,13.494,286.506,0,269.921,0z M143.299,53.225
|
C286.506,300,300,286.506,300,269.92V30.08C300,13.494,286.506,0,269.921,0z M143.299,53.225
|
||||||
c3.583-11.796,11.53-21.482,22.377-27.275c6.652-3.553,14.139-5.431,21.648-5.431c15.026,0,28.906,7.216,37.501,19.173
|
c3.583-11.796,11.53-21.482,22.377-27.275c6.652-3.553,14.139-5.431,21.648-5.431c15.026,0,28.906,7.216,37.501,19.173
|
||||||
c0.573,0.797,1.123,1.615,1.647,2.454c0.56,0.895,1.092,1.812,1.594,2.752c5.791,10.847,7.009,23.317,3.426,35.113
|
c0.573,0.797,1.123,1.615,1.647,2.454c0.56,0.895,1.092,1.812,1.594,2.752c5.791,10.847,7.009,23.317,3.426,35.113
|
||||||
@ -16,8 +18,11 @@ export default function BuySatsCheckedIcon(props) {
|
|||||||
c0.334-2.09,0.804-4.173,1.43-6.234C51.112,98.94,59.06,89.254,69.907,83.462c6.651-3.552,14.137-5.43,21.646-5.43
|
c0.334-2.09,0.804-4.173,1.43-6.234C51.112,98.94,59.06,89.254,69.907,83.462c6.651-3.552,14.137-5.43,21.646-5.43
|
||||||
c17.099,0,32.711,9.342,40.743,24.379c1.23,2.303,2.263,4.71,3.086,7.188c10.192-4.4,13.895-4.946,15.812-4.946
|
c17.099,0,32.711,9.342,40.743,24.379c1.23,2.303,2.263,4.71,3.086,7.188c10.192-4.4,13.895-4.946,15.812-4.946
|
||||||
c0.863,0,1.699,0.101,2.484,0.3c15.838,4.071,41.292,16.888,59.836,27.527c16.43,9.425,27.969,17.124,34.295,22.881
|
c0.863,0,1.699,0.101,2.484,0.3c15.838,4.071,41.292,16.888,59.836,27.527c16.43,9.425,27.969,17.124,34.295,22.881
|
||||||
C253.963,160.965,254.477,164.032,254.473,166.466L254.473,166.466z"/>
|
C253.963,160.965,254.477,164.032,254.473,166.466L254.473,166.466z'
|
||||||
<path fill={props.color} d="M111.93,162.154c-14.119,7.541-30.589,6.39-43.265-1.563c-2.595,1.757-4.684,3.269-6.238,4.499
|
/>
|
||||||
|
<path
|
||||||
|
fill={props.color}
|
||||||
|
d='M111.93,162.154c-14.119,7.541-30.589,6.39-43.265-1.563c-2.595,1.757-4.684,3.269-6.238,4.499
|
||||||
l56.336,33.61v-0.001c-0.178-1.596-0.265-3.194-0.264-4.787c0.006-8.962,2.806-17.76,8.005-25.075
|
l56.336,33.61v-0.001c-0.178-1.596-0.265-3.194-0.264-4.787c0.006-8.962,2.806-17.76,8.005-25.075
|
||||||
c0.347-0.488,0.704-0.969,1.072-1.443c0.654-0.843,1.341-1.664,2.061-2.461c0.72-0.796,1.473-1.568,2.257-2.314
|
c0.347-0.488,0.704-0.969,1.072-1.443c0.654-0.843,1.341-1.664,2.061-2.461c0.72-0.796,1.473-1.568,2.257-2.314
|
||||||
c2.746-2.611,5.884-4.899,9.387-6.769c20.966-11.197,47.131-3.25,58.332,17.717c1.73,3.242,3.001,6.613,3.84,10.029l-7.986,4.907
|
c2.746-2.611,5.884-4.899,9.387-6.769c20.966-11.197,47.131-3.25,58.332,17.717c1.73,3.242,3.001,6.613,3.84,10.029l-7.986,4.907
|
||||||
@ -31,8 +36,11 @@ export default function BuySatsCheckedIcon(props) {
|
|||||||
z M167.4,205.748l-3.352-2.992l-3.459-3.084l-5.443-4.857l-2.891-2.582l-5.443-4.855l-2.047-1.826l0.58-0.649l4.246-4.757
|
z M167.4,205.748l-3.352-2.992l-3.459-3.084l-5.443-4.857l-2.891-2.582l-5.443-4.855l-2.047-1.826l0.58-0.649l4.246-4.757
|
||||||
l0.928,0.83l1.736,1.547l5.439,4.855l2.893,2.583l5.446,4.856l3.457,3.084l4.358,3.887L167.4,205.748z M180.826,197.5l-2.883,1.771
|
l0.928,0.83l1.736,1.547l5.439,4.855l2.893,2.583l5.446,4.856l3.457,3.084l4.358,3.887L167.4,205.748z M180.826,197.5l-2.883,1.771
|
||||||
l-4.996-4.455l-3.456-3.086l-5.442-4.855l-2.895-2.584l-5.442-4.855l-2.819-2.518l4.824-5.408l0.928,0.83l2.51,2.239l5.441,4.856
|
l-4.996-4.455l-3.456-3.086l-5.442-4.855l-2.895-2.584l-5.442-4.855l-2.819-2.518l4.824-5.408l0.928,0.83l2.51,2.239l5.441,4.856
|
||||||
l2.894,2.582l5.444,4.857l3.457,3.085l5.443,4.856l0.554,0.493l0.001,0.001L180.826,197.5z"/>
|
l2.894,2.582l5.444,4.857l3.457,3.085l5.443,4.856l0.554,0.493l0.001,0.001L180.826,197.5z'
|
||||||
<path fill={props.color} d="M187.19,100.922c4.427,0.034,8.908-0.79,13.194-2.546c1.071-0.439,2.131-0.937,3.174-1.494
|
/>
|
||||||
|
<path
|
||||||
|
fill={props.color}
|
||||||
|
d='M187.19,100.922c4.427,0.034,8.908-0.79,13.194-2.546c1.071-0.439,2.131-0.937,3.174-1.494
|
||||||
c16.688-8.912,23.012-29.74,14.104-46.428c-6.13-11.472-17.889-18.046-30.062-18.139c-5.533-0.042-11.152,1.255-16.367,4.04
|
c16.688-8.912,23.012-29.74,14.104-46.428c-6.13-11.472-17.889-18.046-30.062-18.139c-5.533-0.042-11.152,1.255-16.367,4.04
|
||||||
c-16.688,8.913-23.014,29.737-14.105,46.427C163.255,94.253,175.016,100.829,187.19,100.922z M165.298,86.425l6.491-7.145v0
|
c-16.688,8.913-23.014,29.737-14.105,46.427C163.255,94.253,175.016,100.829,187.19,100.922z M165.298,86.425l6.491-7.145v0
|
||||||
l4.895,4.44l-6.49,7.147L165.298,86.425z M189.747,90.282l-0.929-0.826l-1.856-1.658l-5.442-4.857l-3.457-3.085L172.618,75
|
l4.895,4.44l-6.49,7.147L165.298,86.425z M189.747,90.282l-0.929-0.826l-1.856-1.658l-5.442-4.857l-3.457-3.085L172.618,75
|
||||||
@ -41,12 +49,21 @@ export default function BuySatsCheckedIcon(props) {
|
|||||||
M183.525,44.256l0.928,0.83l2.51,2.24l5.439,4.856l2.896,2.582l5.444,4.857l3.457,3.084l5.443,4.857l0.629,0.564l-4.822,5.408
|
M183.525,44.256l0.928,0.83l2.51,2.24l5.439,4.856l2.896,2.582l5.444,4.857l3.457,3.084l5.443,4.857l0.629,0.564l-4.822,5.408
|
||||||
l-1.25-1.116l-5.443-4.856l-3.458-3.085l-5.442-4.856l-2.895-2.583l-5.441-4.856l-2.824-2.517L183.525,44.256z M176.328,53.72
|
l-1.25-1.116l-5.443-4.856l-3.458-3.085l-5.442-4.856l-2.895-2.583l-5.441-4.856l-2.824-2.517L183.525,44.256z M176.328,53.72
|
||||||
l1.734,1.548l5.442,4.856l2.894,2.581l5.442,4.857l3.457,3.086l5.444,4.855l1.404,1.257l-4.821,5.406l-0.001,0l-0.928-0.826
|
l1.734,1.548l5.442,4.856l2.894,2.581l5.442,4.857l3.457,3.086l5.444,4.855l1.404,1.257l-4.821,5.406l-0.001,0l-0.928-0.826
|
||||||
l-1.099-0.981l-5.442-4.856l-3.457-3.085l-5.444-4.856l-2.892-2.583l-5.444-4.855l-2.046-1.825l4.824-5.409L176.328,53.72z"/>
|
l-1.099-0.981l-5.442-4.856l-3.457-3.085l-5.444-4.856l-2.892-2.583l-5.444-4.855l-2.046-1.825l4.824-5.409L176.328,53.72z'
|
||||||
<polygon fill={props.color} points="59.715,174.898 59.715,256.418 94.226,195.484 "/>
|
/>
|
||||||
<path fill={props.color} d="M241.417,259.706c0.151-0.657,0.24-1.34,0.24-2.042v-84.453l-36.673,22.176L241.417,259.706z"/>
|
<polygon fill={props.color} points='59.715,174.898 59.715,256.418 94.226,195.484 ' />
|
||||||
<path fill={props.color} d="M196.584,200.466l-46.69,28.232l-47.237-28.183l-37.129,65.557l0,0.001c0.994,0.379,2.065,0.595,3.19,0.595
|
<path
|
||||||
h163.938c0.462,0,0.912-0.047,1.357-0.113l-0.001-0.002L196.584,200.466z"/>
|
fill={props.color}
|
||||||
<path fill={props.color} d="M68.179,149.165c2.65,2.481,5.651,4.502,8.876,6.015c9.464,4.428,20.827,4.506,30.732-0.785
|
d='M241.417,259.706c0.151-0.657,0.24-1.34,0.24-2.042v-84.453l-36.673,22.176L241.417,259.706z'
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill={props.color}
|
||||||
|
d='M196.584,200.466l-46.69,28.232l-47.237-28.183l-37.129,65.557l0,0.001c0.994,0.379,2.065,0.595,3.19,0.595
|
||||||
|
h163.938c0.462,0,0.912-0.047,1.357-0.113l-0.001-0.002L196.584,200.466z'
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill={props.color}
|
||||||
|
d='M68.179,149.165c2.65,2.481,5.651,4.502,8.876,6.015c9.464,4.428,20.827,4.506,30.732-0.785
|
||||||
c1.276-0.682,2.492-1.434,3.646-2.247c8.07-5.697,13.056-14.459,14.224-23.819c0.222-1.774,0.307-3.57,0.25-5.371
|
c1.276-0.682,2.492-1.434,3.646-2.247c8.07-5.697,13.056-14.459,14.224-23.819c0.222-1.774,0.307-3.57,0.25-5.371
|
||||||
c-0.058-1.802-0.258-3.608-0.607-5.403c-0.635-3.269-1.76-6.499-3.407-9.585c-8.914-16.688-29.741-23.015-46.43-14.101
|
c-0.058-1.802-0.258-3.608-0.607-5.403c-0.635-3.269-1.76-6.499-3.407-9.585c-8.914-16.688-29.741-23.015-46.43-14.101
|
||||||
c-11.474,6.126-18.048,17.884-18.14,30.057c-0.042,5.533,1.255,11.151,4.04,16.365C63.182,143.697,65.503,146.663,68.179,149.165z
|
c-11.474,6.126-18.048,17.884-18.14,30.057c-0.042,5.533,1.255,11.151,4.04,16.365C63.182,143.697,65.503,146.663,68.179,149.165z
|
||||||
@ -54,8 +71,9 @@ export default function BuySatsCheckedIcon(props) {
|
|||||||
l-0.927-0.827l-0.867-0.773l-7.715-6.884l-17.241-15.383l0,0l4.82-5.408l19.058,17.005l7.695,6.864L98.659,142.548z
|
l-0.927-0.827l-0.867-0.773l-7.715-6.884l-17.241-15.383l0,0l4.82-5.408l19.058,17.005l7.695,6.864L98.659,142.548z
|
||||||
M101.553,139.68l-0.926-0.827l-5.958-5.316l-19.866-17.726l4.828-5.408l0.926,0.829l20.863,18.616l4.958,4.424L101.553,139.68z
|
M101.553,139.68l-0.926-0.827l-5.958-5.316l-19.866-17.726l4.828-5.408l0.926,0.829l20.863,18.616l4.958,4.424L101.553,139.68z
|
||||||
M109.679,131.046l-3.936-3.513l-22.816-20.356l4.828-5.407l0.929,0.83l23.915,21.338l1.904,1.702L109.679,131.046z
|
M109.679,131.046l-3.936-3.513l-22.816-20.356l4.828-5.407l0.929,0.83l23.915,21.338l1.904,1.702L109.679,131.046z
|
||||||
M101.086,109.122l6.486-7.146l4.892,4.44l0.002,0.002l-6.489,7.149l-4.894-4.442L101.086,109.122z"/>
|
M101.086,109.122l6.486-7.146l4.892,4.44l0.002,0.002l-6.489,7.149l-4.894-4.442L101.086,109.122z'
|
||||||
</g>
|
/>
|
||||||
</SvgIcon>
|
</g>
|
||||||
);
|
</SvgIcon>
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import { SvgIcon } from "@mui/material"
|
import { SvgIcon } from '@mui/material';
|
||||||
|
|
||||||
export default function CataloniaFlag(props) {
|
export default function CataloniaFlag(props) {
|
||||||
return (
|
return (
|
||||||
<SvgIcon {...props} x="0px" y="0px" viewBox="0 0 810 540">
|
<SvgIcon {...props} x='0px' y='0px' viewBox='0 0 810 540'>
|
||||||
<rect width="810" height="540" fill="#FCDD09"/>
|
<rect width='810' height='540' fill='#FCDD09' />
|
||||||
<path stroke="#DA121A" strokeWidth="60" d="M0,90H810m0,120H0m0,120H810m0,120H0"/>
|
<path stroke='#DA121A' strokeWidth='60' d='M0,90H810m0,120H0m0,120H810m0,120H0' />
|
||||||
</SvgIcon>
|
</SvgIcon>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,21 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import { SvgIcon } from "@mui/material"
|
import { SvgIcon } from '@mui/material';
|
||||||
|
|
||||||
export default function EarthIcon(props) {
|
export default function EarthIcon(props) {
|
||||||
return (
|
return (
|
||||||
<SvgIcon {...props} x="0px" y="0px" viewBox="0 0 440.45 440.45" >
|
<SvgIcon {...props} x='0px' y='0px' viewBox='0 0 440.45 440.45'>
|
||||||
<g id="XMLID_34_">
|
<g id='XMLID_34_'>
|
||||||
<g>
|
<g>
|
||||||
<path style={{fill:"#1EA6C6"}} d="M102.62,211.975c0.02,0.08,0.04,0.15,0.06,0.23c1.91,7.94,3.42,19.8,1.63,35.19
|
<path
|
||||||
|
style={{ fill: '#1EA6C6' }}
|
||||||
|
d='M102.62,211.975c0.02,0.08,0.04,0.15,0.06,0.23c1.91,7.94,3.42,19.8,1.63,35.19
|
||||||
c-1.91,16.48,5.5,32.66,19.11,42.15l18.56,12.95c0,0-6.37,48.72,11.31,74.36v0.01C65.91,359.665,0,282.645,0,190.225
|
c-1.91,16.48,5.5,32.66,19.11,42.15l18.56,12.95c0,0-6.37,48.72,11.31,74.36v0.01C65.91,359.665,0,282.645,0,190.225
|
||||||
c0-53.81,22.35-102.41,58.27-137c-14.15,28.48-28.54,72.45-8.29,109.27c9.27,16.85,23.9,27.78,40.15,34.8
|
c0-53.81,22.35-102.41,58.27-137c-14.15,28.48-28.54,72.45-8.29,109.27c9.27,16.85,23.9,27.78,40.15,34.8
|
||||||
C96.36,199.975,101.02,205.395,102.62,211.975z"/>
|
C96.36,199.975,101.02,205.395,102.62,211.975z'
|
||||||
<path style={{fill:"#1EA6C6"}} d="M190.23,0.005c41.46,0,79.82,13.26,111.07,35.79c0,0-16.37,25.11-15.71,50.17
|
/>
|
||||||
|
<path
|
||||||
|
style={{ fill: '#1EA6C6' }}
|
||||||
|
d='M190.23,0.005c41.46,0,79.82,13.26,111.07,35.79c0,0-16.37,25.11-15.71,50.17
|
||||||
c0.15,5.99,4.84,10.89,10.81,11.52c0.42,0.04,0.85,0.07,1.27,0.07c4.55,0,8.75-2.58,10.81-6.73c4.38-8.78,15.91-19.42,45.02,1.77
|
c0.15,5.99,4.84,10.89,10.81,11.52c0.42,0.04,0.85,0.07,1.27,0.07c4.55,0,8.75-2.58,10.81-6.73c4.38-8.78,15.91-19.42,45.02,1.77
|
||||||
l0.01-0.01c2.17,3.61,4.22,7.3,6.14,11.07c0,0-10.16,2.28-23.77,0.6c-3.78-0.47-7.6,0.45-10.69,2.67
|
l0.01-0.01c2.17,3.61,4.22,7.3,6.14,11.07c0,0-10.16,2.28-23.77,0.6c-3.78-0.47-7.6,0.45-10.69,2.67
|
||||||
c-2.15,1.55-4.62,3.78-7.36,6.53c-13.89,13.96-16.19,43-16.19,43c-0.27,6.06,0,12.76,0.97,20.16
|
c-2.15,1.55-4.62,3.78-7.36,6.53c-13.89,13.96-16.19,43-16.19,43c-0.27,6.06,0,12.76,0.97,20.16
|
||||||
@ -20,28 +25,47 @@ export default function EarthIcon(props) {
|
|||||||
c-16.59-10.07-36.14-23.07-48.73-35.16c-6.33-6.07-15.04-8.98-23.76-8.04c-11.2,1.21-27.07,3.65-42.8,8.55
|
c-16.59-10.07-36.14-23.07-48.73-35.16c-6.33-6.07-15.04-8.98-23.76-8.04c-11.2,1.21-27.07,3.65-42.8,8.55
|
||||||
c2.7-26.79-43.7-50.71-31.7-71.71c6.5-11.39,17.42-11.6,26.05-9.41c6.87,1.74,14.08-0.76,18.54-6.27
|
c2.7-26.79-43.7-50.71-31.7-71.71c6.5-11.39,17.42-11.6,26.05-9.41c6.87,1.74,14.08-0.76,18.54-6.27
|
||||||
c10.56-13.03,33.63-25.24,50.49-32.96c11.05-5.05,14.62-18.98,7.36-28.71c-22.27-29.9-53.82-49.59-53.82-49.59
|
c10.56-13.03,33.63-25.24,50.49-32.96c11.05-5.05,14.62-18.98,7.36-28.71c-22.27-29.9-53.82-49.59-53.82-49.59
|
||||||
C141.44,4.815,165.27,0.005,190.23,0.005z M197.98,61.495l23-30c0,0-10-9-46-12C167.79,18.895,194.98,38.495,197.98,61.495z"/>
|
C141.44,4.815,165.27,0.005,190.23,0.005z M197.98,61.495l23-30c0,0-10-9-46-12C167.79,18.895,194.98,38.495,197.98,61.495z'
|
||||||
<path style={{fill:"#F7CF52"}} d="M353.51,92.585l-0.01,0.01c-29.11-21.19-40.64-10.55-45.02-1.77c-2.06,4.15-6.26,6.73-10.81,6.73
|
/>
|
||||||
|
<path
|
||||||
|
style={{ fill: '#F7CF52' }}
|
||||||
|
d='M353.51,92.585l-0.01,0.01c-29.11-21.19-40.64-10.55-45.02-1.77c-2.06,4.15-6.26,6.73-10.81,6.73
|
||||||
c-0.42,0-0.85-0.03-1.27-0.07c-5.97-0.63-10.66-5.53-10.81-11.52c-0.66-25.06,15.71-50.17,15.71-50.17
|
c-0.42,0-0.85-0.03-1.27-0.07c-5.97-0.63-10.66-5.53-10.81-11.52c-0.66-25.06,15.71-50.17,15.71-50.17
|
||||||
C322.33,50.935,340.14,70.275,353.51,92.585z"/>
|
C322.33,50.935,340.14,70.275,353.51,92.585z'
|
||||||
<path style={{fill:"#F7CF52"}} d="M380.45,190.225c0,22.57-3.93,44.23-11.15,64.32h-0.01c-6.07-10.32-8.37-22.55-8.98-33.34
|
/>
|
||||||
|
<path
|
||||||
|
style={{ fill: '#F7CF52' }}
|
||||||
|
d='M380.45,190.225c0,22.57-3.93,44.23-11.15,64.32h-0.01c-6.07-10.32-8.37-22.55-8.98-33.34
|
||||||
c-0.68-11.96-11.49-20.89-23.33-19.05c-0.24,0.03-0.48,0.07-0.72,0.1c-16.41,2.4-31.48-9.2-33.65-25.64
|
c-0.68-11.96-11.49-20.89-23.33-19.05c-0.24,0.03-0.48,0.07-0.72,0.1c-16.41,2.4-31.48-9.2-33.65-25.64
|
||||||
c-0.97-7.4-1.24-14.1-0.97-20.16c0,0,2.3-29.04,16.19-43c2.74-2.75,5.21-4.98,7.36-6.53c3.09-2.22,6.91-3.14,10.69-2.67
|
c-0.97-7.4-1.24-14.1-0.97-20.16c0,0,2.3-29.04,16.19-43c2.74-2.75,5.21-4.98,7.36-6.53c3.09-2.22,6.91-3.14,10.69-2.67
|
||||||
c13.61,1.68,23.77-0.6,23.77-0.6C372.95,129.625,380.45,159.045,380.45,190.225z"/>
|
c13.61,1.68,23.77-0.6,23.77-0.6C372.95,129.625,380.45,159.045,380.45,190.225z'
|
||||||
<path style={{fill:"#F7CF52"}} d="M220.98,31.495l-23,30c-3-23-30.19-42.6-23-42C210.98,22.495,220.98,31.495,220.98,31.495z"/>
|
/>
|
||||||
<path style={{fill:"#F7CF52"}} d="M173.42,63.145c7.26,9.73,3.69,23.66-7.36,28.71c-16.86,7.72-39.93,19.93-50.49,32.96
|
<path
|
||||||
|
style={{ fill: '#F7CF52' }}
|
||||||
|
d='M220.98,31.495l-23,30c-3-23-30.19-42.6-23-42C210.98,22.495,220.98,31.495,220.98,31.495z'
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
style={{ fill: '#F7CF52' }}
|
||||||
|
d='M173.42,63.145c7.26,9.73,3.69,23.66-7.36,28.71c-16.86,7.72-39.93,19.93-50.49,32.96
|
||||||
c-4.46,5.51-11.67,8.01-18.54,6.27c-8.63-2.19-19.55-1.98-26.05,9.41c-12,21,34.4,44.92,31.7,71.71
|
c-4.46,5.51-11.67,8.01-18.54,6.27c-8.63-2.19-19.55-1.98-26.05,9.41c-12,21,34.4,44.92,31.7,71.71
|
||||||
c-0.02-0.08-0.04-0.15-0.06-0.23c-1.6-6.58-6.26-12-12.49-14.68c-16.25-7.02-30.88-17.95-40.15-34.8
|
c-0.02-0.08-0.04-0.15-0.06-0.23c-1.6-6.58-6.26-12-12.49-14.68c-16.25-7.02-30.88-17.95-40.15-34.8
|
||||||
c-20.25-36.82-5.86-80.79,8.29-109.27c17.54-16.91,38.33-30.47,61.33-39.67C119.6,13.555,151.15,33.245,173.42,63.145z"/>
|
c-20.25-36.82-5.86-80.79,8.29-109.27c17.54-16.91,38.33-30.47,61.33-39.67C119.6,13.555,151.15,33.245,173.42,63.145z'
|
||||||
<path style={{fill:"#F7CF52"}} d="M217.97,246.855c17.77,10.79,21.93,34.83,8.76,50.92c-7.41,9.05-15.93,18.74-24.47,28.12
|
/>
|
||||||
|
<path
|
||||||
|
style={{ fill: '#F7CF52' }}
|
||||||
|
d='M217.97,246.855c17.77,10.79,21.93,34.83,8.76,50.92c-7.41,9.05-15.93,18.74-24.47,28.12
|
||||||
l-29.58,31.37c-14.04,14.58-19.39,19.59-19.39,19.59c-17.68-25.64-11.31-74.36-11.31-74.36l-18.56-12.95
|
l-29.58,31.37c-14.04,14.58-19.39,19.59-19.39,19.59c-17.68-25.64-11.31-74.36-11.31-74.36l-18.56-12.95
|
||||||
c-13.61-9.49-21.02-25.67-19.11-42.15c1.79-15.39,0.28-27.25-1.63-35.19c15.73-4.9,31.6-7.34,42.8-8.55
|
c-13.61-9.49-21.02-25.67-19.11-42.15c1.79-15.39,0.28-27.25-1.63-35.19c15.73-4.9,31.6-7.34,42.8-8.55
|
||||||
c8.72-0.94,17.43,1.97,23.76,8.04C181.83,223.785,201.38,236.785,217.97,246.855z"/>
|
c8.72-0.94,17.43,1.97,23.76,8.04C181.83,223.785,201.38,236.785,217.97,246.855z'
|
||||||
</g>
|
/>
|
||||||
</g>
|
</g>
|
||||||
<path style={{opacity:"0.3",fill:"#808080",enableBackground:"new"}} d="M190.23,0.005c5.8,0,11.54,0.26,17.2,0.77
|
</g>
|
||||||
|
<path
|
||||||
|
style={{ opacity: '0.3', fill: '#808080', enableBackground: 'new' }}
|
||||||
|
d='M190.23,0.005c5.8,0,11.54,0.26,17.2,0.77
|
||||||
C110.48,9.515,34.5,90.995,34.5,190.225c0,99.25,76.01,180.74,172.99,189.45c-5.68,0.51-11.44,0.77-17.26,0.77
|
C110.48,9.515,34.5,90.995,34.5,190.225c0,99.25,76.01,180.74,172.99,189.45c-5.68,0.51-11.44,0.77-17.26,0.77
|
||||||
C85.17,380.445,0,295.285,0,190.225S85.17,0.005,190.23,0.005z"/>
|
C85.17,380.445,0,295.285,0,190.225S85.17,0.005,190.23,0.005z'
|
||||||
</SvgIcon>
|
/>
|
||||||
);
|
</SvgIcon>
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import { SvgIcon } from "@mui/material"
|
import { SvgIcon } from '@mui/material';
|
||||||
|
|
||||||
export default function ExportIcon(props) {
|
export default function ExportIcon(props) {
|
||||||
return (
|
return (
|
||||||
<SvgIcon sx={props.sx} color={props.color} viewBox="0 0 576 512">
|
<SvgIcon sx={props.sx} color={props.color} viewBox='0 0 576 512'>
|
||||||
<path d="M192 312C192 298.8 202.8 288 216 288H384V160H256c-17.67 0-32-14.33-32-32L224 0H48C21.49 0 0 21.49 0 48v416C0 490.5 21.49 512 48 512h288c26.51 0 48-21.49 48-48v-128H216C202.8 336 192 325.3 192 312zM256 0v128h128L256 0zM568.1 295l-80-80c-9.375-9.375-24.56-9.375-33.94 0s-9.375 24.56 0 33.94L494.1 288H384v48h110.1l-39.03 39.03C450.3 379.7 448 385.8 448 392s2.344 12.28 7.031 16.97c9.375 9.375 24.56 9.375 33.94 0l80-80C578.3 319.6 578.3 304.4 568.1 295z"/>
|
<path d='M192 312C192 298.8 202.8 288 216 288H384V160H256c-17.67 0-32-14.33-32-32L224 0H48C21.49 0 0 21.49 0 48v416C0 490.5 21.49 512 48 512h288c26.51 0 48-21.49 48-48v-128H216C202.8 336 192 325.3 192 312zM256 0v128h128L256 0zM568.1 295l-80-80c-9.375-9.375-24.56-9.375-33.94 0s-9.375 24.56 0 33.94L494.1 288H384v48h110.1l-39.03 39.03C450.3 379.7 448 385.8 448 392s2.344 12.28 7.031 16.97c9.375 9.375 24.56 9.375 33.94 0l80-80C578.3 319.6 578.3 304.4 568.1 295z' />
|
||||||
</SvgIcon>
|
</SvgIcon>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,48 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import { SvgIcon } from "@mui/material"
|
import { SvgIcon } from '@mui/material';
|
||||||
|
|
||||||
export default function GoldIcon(props) {
|
export default function GoldIcon(props) {
|
||||||
return (
|
return (
|
||||||
<SvgIcon {...props} x="0px" y="0px" viewBox="0 0 511.882 511.882">
|
<SvgIcon {...props} x='0px' y='0px' viewBox='0 0 511.882 511.882'>
|
||||||
<polygon style={{fill:"#F6BB42"}} points="350.216,176.572 278.374,158.615 37.038,264.123 0,338.207 125.753,374.324 386.13,258.531
|
<polygon
|
||||||
"/>
|
style={{ fill: '#F6BB42' }}
|
||||||
<polygon style={{fill:"#FFCE54"}} points="350.216,176.572 107.756,284.345 125.753,374.324 386.13,258.531 "/>
|
points='350.216,176.572 278.374,158.615 37.038,264.123 0,338.207 125.753,374.324 386.13,258.531
|
||||||
<polygon style={{fill:"#E8AA3D"}} points="107.756,284.345 37.038,264.123 0.015,338.207 125.753,374.324 "/>
|
'
|
||||||
<polygon style={{fill:"#F6BB42"}} points="475.969,212.682 404.127,194.717 162.791,300.232 125.753,374.324 251.504,410.41
|
/>
|
||||||
511.882,294.625 "/>
|
<polygon
|
||||||
<polygon style={{fill:"#FFCE54"}} points="475.969,212.682 233.508,320.431 251.504,410.41 511.882,294.625 "/>
|
style={{ fill: '#FFCE54' }}
|
||||||
<polygon style={{fill:"#E8AA3D"}} points="233.508,320.431 162.791,300.232 125.753,374.324 251.504,410.41 "/>
|
points='350.216,176.572 107.756,284.345 125.753,374.324 386.13,258.531 '
|
||||||
<polygon style={{fill:"#F6BB42"}} points="396.316,119.429 324.488,101.473 103.867,198.435 66.843,272.519 192.596,308.621
|
/>
|
||||||
432.245,201.379 "/>
|
<polygon
|
||||||
<polygon style={{fill:"#FFCE54"}} points="396.316,119.429 174.6,218.641 192.596,308.621 432.245,201.379 "/>
|
style={{ fill: '#E8AA3D' }}
|
||||||
<polygon style={{fill:"#E8AA3D"}} points="174.6,218.641 103.867,198.435 66.843,272.519 192.596,308.621 "/>
|
points='107.756,284.345 37.038,264.123 0.015,338.207 125.753,374.324 '
|
||||||
</SvgIcon>
|
/>
|
||||||
);
|
<polygon
|
||||||
}
|
style={{ fill: '#F6BB42' }}
|
||||||
|
points='475.969,212.682 404.127,194.717 162.791,300.232 125.753,374.324 251.504,410.41
|
||||||
|
511.882,294.625 '
|
||||||
|
/>
|
||||||
|
<polygon
|
||||||
|
style={{ fill: '#FFCE54' }}
|
||||||
|
points='475.969,212.682 233.508,320.431 251.504,410.41 511.882,294.625 '
|
||||||
|
/>
|
||||||
|
<polygon
|
||||||
|
style={{ fill: '#E8AA3D' }}
|
||||||
|
points='233.508,320.431 162.791,300.232 125.753,374.324 251.504,410.41 '
|
||||||
|
/>
|
||||||
|
<polygon
|
||||||
|
style={{ fill: '#F6BB42' }}
|
||||||
|
points='396.316,119.429 324.488,101.473 103.867,198.435 66.843,272.519 192.596,308.621
|
||||||
|
432.245,201.379 '
|
||||||
|
/>
|
||||||
|
<polygon
|
||||||
|
style={{ fill: '#FFCE54' }}
|
||||||
|
points='396.316,119.429 174.6,218.641 192.596,308.621 432.245,201.379 '
|
||||||
|
/>
|
||||||
|
<polygon
|
||||||
|
style={{ fill: '#E8AA3D' }}
|
||||||
|
points='174.6,218.641 103.867,198.435 66.843,272.519 192.596,308.621 '
|
||||||
|
/>
|
||||||
|
</SvgIcon>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import { SvgIcon } from "@mui/material"
|
import { SvgIcon } from '@mui/material';
|
||||||
|
|
||||||
export default function NewTabIcon(props) {
|
export default function NewTabIcon(props) {
|
||||||
return (
|
return (
|
||||||
<SvgIcon sx={props.sx} color={props.color} viewBox="0 0 448 512">
|
<SvgIcon sx={props.sx} color={props.color} viewBox='0 0 448 512'>
|
||||||
<path d="M256 64C256 46.33 270.3 32 288 32H415.1C415.1 32 415.1 32 415.1 32C420.3 32 424.5 32.86 428.2 34.43C431.1 35.98 435.5 38.27 438.6 41.3C438.6 41.35 438.6 41.4 438.7 41.44C444.9 47.66 447.1 55.78 448 63.9C448 63.94 448 63.97 448 64V192C448 209.7 433.7 224 416 224C398.3 224 384 209.7 384 192V141.3L214.6 310.6C202.1 323.1 181.9 323.1 169.4 310.6C156.9 298.1 156.9 277.9 169.4 265.4L338.7 96H288C270.3 96 256 81.67 256 64V64zM0 128C0 92.65 28.65 64 64 64H160C177.7 64 192 78.33 192 96C192 113.7 177.7 128 160 128H64V416H352V320C352 302.3 366.3 288 384 288C401.7 288 416 302.3 416 320V416C416 451.3 387.3 480 352 480H64C28.65 480 0 451.3 0 416V128z"/>
|
<path d='M256 64C256 46.33 270.3 32 288 32H415.1C415.1 32 415.1 32 415.1 32C420.3 32 424.5 32.86 428.2 34.43C431.1 35.98 435.5 38.27 438.6 41.3C438.6 41.35 438.6 41.4 438.7 41.44C444.9 47.66 447.1 55.78 448 63.9C448 63.94 448 63.97 448 64V192C448 209.7 433.7 224 416 224C398.3 224 384 209.7 384 192V141.3L214.6 310.6C202.1 323.1 181.9 323.1 169.4 310.6C156.9 298.1 156.9 277.9 169.4 265.4L338.7 96H288C270.3 96 256 81.67 256 64V64zM0 128C0 92.65 28.65 64 64 64H160C177.7 64 192 78.33 192 96C192 113.7 177.7 128 160 128H64V416H352V320C352 302.3 366.3 288 384 288C401.7 288 416 302.3 416 320V416C416 451.3 387.3 480 352 480H64C28.65 480 0 451.3 0 416V128z' />
|
||||||
</SvgIcon>
|
</SvgIcon>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import { SvgIcon } from "@mui/material"
|
import { SvgIcon } from '@mui/material';
|
||||||
|
|
||||||
export default function RoboSatsIcon(props) {
|
export default function RoboSatsIcon(props) {
|
||||||
return (
|
return (
|
||||||
<SvgIcon {...props} x="0px" y="0px" width="1000px" height="1000px" viewBox="0 0 1000 900">
|
<SvgIcon {...props} x='0px' y='0px' width='1000px' height='1000px' viewBox='0 0 1000 900'>
|
||||||
<g>
|
<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
|
<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-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
|
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
|
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
|
||||||
@ -15,46 +16,64 @@ export default function RoboSatsIcon(props) {
|
|||||||
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
|
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
|
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
|
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
|
||||||
<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
|
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-0.721,25.455-21.862,45.67-47.178,45.104C465.779,654.273,445.244,633.082,445.93,607.736z"/>
|
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="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
|
/>
|
||||||
|
<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
|
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"/>
|
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
|
/>
|
||||||
|
<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
|
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>
|
</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
|
<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
|
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
|
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"/>
|
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
|
/>
|
||||||
|
<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-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
|
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
|
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
|
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
|
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
|
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"/>
|
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
|
/>
|
||||||
|
<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
|
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
|
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
|
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
|
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"/>
|
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
|
/>
|
||||||
|
<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-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
|
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
|
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
|
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
|
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
|
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"/>
|
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
|
/>
|
||||||
|
<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
|
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
|
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
|
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
|
||||||
@ -62,11 +81,15 @@ export default function RoboSatsIcon(props) {
|
|||||||
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
|
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
|
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
|
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"/>
|
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
|
||||||
<path d="M760.999,775.275h-28.916v78.644h-19.45v-78.644h-28.526v-15.754h76.893V775.275z"/>
|
d='M661.673,834.469H627.57l-6.483,19.45h-20.682l35.14-94.397h18.023l35.335,94.397h-20.683L661.673,834.469z
|
||||||
<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
|
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
|
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
|
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
|
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
|
||||||
@ -74,8 +97,9 @@ export default function RoboSatsIcon(props) {
|
|||||||
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
|
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
|
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
|
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"/>
|
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>
|
</g>
|
||||||
);
|
</SvgIcon>
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import { SvgIcon } from "@mui/material"
|
import { SvgIcon } from '@mui/material';
|
||||||
|
|
||||||
export default function RoboSatsNoTextIcon(props) {
|
export default function RoboSatsNoTextIcon(props) {
|
||||||
return (
|
return (
|
||||||
<SvgIcon {...props} x="0px" y="0px" width="1000px" height="1000px" viewBox="0 0 1000 800">
|
<SvgIcon {...props} x='0px' y='0px' width='1000px' height='1000px' viewBox='0 0 1000 800'>
|
||||||
<g>
|
<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
|
<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-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
|
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
|
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
|
||||||
@ -15,18 +16,27 @@ export default function RoboSatsNoTextIcon(props) {
|
|||||||
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
|
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
|
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
|
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
|
||||||
<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
|
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-0.721,25.455-21.862,45.67-47.178,45.104C465.779,654.273,445.244,633.082,445.93,607.736z"/>
|
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="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
|
/>
|
||||||
|
<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
|
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"/>
|
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
|
/>
|
||||||
|
<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
|
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>
|
/>
|
||||||
</SvgIcon>
|
</g>
|
||||||
);
|
</SvgIcon>
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import { SvgIcon } from "@mui/material"
|
import { SvgIcon } from '@mui/material';
|
||||||
|
|
||||||
export default function RoboSatsTextIcon(props) {
|
export default function RoboSatsTextIcon(props) {
|
||||||
return (
|
return (
|
||||||
<SvgIcon {...props} x="0px" y="0px" width="2000px" height="1000px" viewBox="0 300 2000 150">
|
<SvgIcon {...props} x='0px' y='0px' width='2000px' height='1000px' viewBox='0 300 2000 150'>
|
||||||
<g>
|
<g>
|
||||||
<path d="M455.556,849.519c10.487-10.606,18.315-22.243,23.484-35.499c11.767-30.177,10.624-59.483-6.55-87.546
|
<path
|
||||||
|
d='M455.556,849.519c10.487-10.606,18.315-22.243,23.484-35.499c11.767-30.177,10.624-59.483-6.55-87.546
|
||||||
c-6.421-10.492-15.644-18.342-24.709-26.363c-42.412-37.528-84.791-75.089-127.178-112.646c-0.23-0.204-0.403-0.473-0.833-0.988
|
c-6.421-10.492-15.644-18.342-24.709-26.363c-42.412-37.528-84.791-75.089-127.178-112.646c-0.23-0.204-0.403-0.473-0.833-0.988
|
||||||
c11.603-7.813,23.158-15.593,34.985-23.557c-6.017-4.258-11.845-8.382-17.938-12.692c7.366-9.069,14.573-17.943,21.752-26.783
|
c11.603-7.813,23.158-15.593,34.985-23.557c-6.017-4.258-11.845-8.382-17.938-12.692c7.366-9.069,14.573-17.943,21.752-26.783
|
||||||
c8.336,4.434,15.519,3.458,20.084-2.588c4.005-5.302,3.629-12.893-0.884-17.858c-4.39-4.829-12.207-5.82-17.747-2.248
|
c8.336,4.434,15.519,3.458,20.084-2.588c4.005-5.302,3.629-12.893-0.884-17.858c-4.39-4.829-12.207-5.82-17.747-2.248
|
||||||
@ -14,42 +15,58 @@ export default function RoboSatsTextIcon(props) {
|
|||||||
c1.134-0.051,2.23-0.144,3.327-0.144c61.359-0.006,122.719-0.134,184.077,0.059c23.582,0.074,47.182,1.188,70.189,6.894
|
c1.134-0.051,2.23-0.144,3.327-0.144c61.359-0.006,122.719-0.134,184.077,0.059c23.582,0.074,47.182,1.188,70.189,6.894
|
||||||
c33.068,8.2,59.95,25.613,78.508,54.766c8.642,13.576,12.927,28.656,14.487,44.482c2.252,22.815,0.823,45.408-5.545,67.547
|
c33.068,8.2,59.95,25.613,78.508,54.766c8.642,13.576,12.927,28.656,14.487,44.482c2.252,22.815,0.823,45.408-5.545,67.547
|
||||||
c-7.479,25.995-23.225,46.343-43.608,63.466c-10.102,8.486-21.167,15.536-32.924,21.505c-0.814,0.413-1.585,0.905-2.597,1.487
|
c-7.479,25.995-23.225,46.343-43.608,63.466c-10.102,8.486-21.167,15.536-32.924,21.505c-0.814,0.413-1.585,0.905-2.597,1.487
|
||||||
c50.553,63.965,100.971,127.76,151.731,191.983C555.434,849.519,505.838,849.519,455.556,849.519z"/>
|
c50.553,63.965,100.971,127.76,151.731,191.983C555.434,849.519,505.838,849.519,455.556,849.519z'
|
||||||
<path d="M255.521,635.166c16.096-0.067,29.067,12.759,29.148,28.827c0.083,16.276-12.776,29.339-28.953,29.405
|
/>
|
||||||
c-16.022,0.067-29.385-13.258-29.278-29.196C226.544,648.168,239.5,635.234,255.521,635.166z"/>
|
<path
|
||||||
<path d="M357.619,772.016c0.441-16.3,13.472-29.043,29.376-28.729c16.465,0.325,29.215,13.623,28.752,29.985
|
d='M255.521,635.166c16.096-0.067,29.067,12.759,29.148,28.827c0.083,16.276-12.776,29.339-28.953,29.405
|
||||||
c-0.451,15.939-13.688,28.597-29.541,28.242C370.048,801.155,357.19,787.886,357.619,772.016z"/>
|
c-16.022,0.067-29.385-13.258-29.278-29.196C226.544,648.168,239.5,635.234,255.521,635.166z'
|
||||||
<path d="M188.111,736.337c14.63,12.955,28.898,25.589,43.417,38.445c-3.115,3.519-6.132,6.927-9.336,10.548
|
/>
|
||||||
|
<path
|
||||||
|
d='M357.619,772.016c0.441-16.3,13.472-29.043,29.376-28.729c16.465,0.325,29.215,13.623,28.752,29.985
|
||||||
|
c-0.451,15.939-13.688,28.597-29.541,28.242C370.048,801.155,357.19,787.886,357.619,772.016z'
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d='M188.111,736.337c14.63,12.955,28.898,25.589,43.417,38.445c-3.115,3.519-6.132,6.927-9.336,10.548
|
||||||
c-3.528-3.123-6.993-6.098-10.344-9.194c-1.96-1.813-3.346-1.561-5.269,0.292c-6.227,5.999-12.67,11.772-18.468,17.114
|
c-3.528-3.123-6.993-6.098-10.344-9.194c-1.96-1.813-3.346-1.561-5.269,0.292c-6.227,5.999-12.67,11.772-18.468,17.114
|
||||||
C188.111,775.57,188.111,756.221,188.111,736.337z"/>
|
C188.111,775.57,188.111,756.221,188.111,736.337z'
|
||||||
<path d="M315.788,849.533c-18.813,0-36.98,0-55.824,0c5.607-5.78,10.793-11.127,16.108-16.606
|
/>
|
||||||
c-3.987-3.574-7.77-6.967-11.734-10.521c3.071-3.48,6.007-6.811,9.173-10.398C287.54,824.461,301.433,836.792,315.788,849.533z"/>
|
<path
|
||||||
|
d='M315.788,849.533c-18.813,0-36.98,0-55.824,0c5.607-5.78,10.793-11.127,16.108-16.606
|
||||||
|
c-3.987-3.574-7.77-6.967-11.734-10.521c3.071-3.48,6.007-6.811,9.173-10.398C287.54,824.461,301.433,836.792,315.788,849.533z'
|
||||||
|
/>
|
||||||
</g>
|
</g>
|
||||||
<g>
|
<g>
|
||||||
<path d="M766.812,758.155c0,18.361-3.246,34.457-9.734,48.289c-6.49,13.834-15.776,24.51-27.859,32.022
|
<path
|
||||||
|
d='M766.812,758.155c0,18.361-3.246,34.457-9.734,48.289c-6.49,13.834-15.776,24.51-27.859,32.022
|
||||||
c-12.085,7.516-25.938,11.273-41.564,11.273c-15.458,0-29.249-3.715-41.374-11.145c-12.127-7.429-21.519-18.039-28.181-31.831
|
c-12.085,7.516-25.938,11.273-41.564,11.273c-15.458,0-29.249-3.715-41.374-11.145c-12.127-7.429-21.519-18.039-28.181-31.831
|
||||||
c-6.66-13.789-10.035-29.653-10.118-47.584v-9.223c0-18.358,3.308-34.521,9.927-48.481c6.617-13.962,15.968-24.678,28.052-32.15
|
c-6.66-13.789-10.035-29.653-10.118-47.584v-9.223c0-18.358,3.308-34.521,9.927-48.481c6.617-13.962,15.968-24.678,28.052-32.15
|
||||||
c12.083-7.471,25.894-11.207,41.437-11.207c15.541,0,29.352,3.735,41.437,11.207c12.083,7.473,21.433,18.188,28.052,32.15
|
c12.083-7.471,25.894-11.207,41.437-11.207c15.541,0,29.352,3.735,41.437,11.207c12.083,7.473,21.433,18.188,28.052,32.15
|
||||||
c6.616,13.961,9.926,30.081,9.926,48.354V758.155L766.812,758.155z M727.873,749.701c0-19.553-3.503-34.411-10.504-44.574
|
c6.616,13.961,9.926,30.081,9.926,48.354V758.155L766.812,758.155z M727.873,749.701c0-19.553-3.503-34.411-10.504-44.574
|
||||||
c-7.003-10.163-16.993-15.243-29.972-15.243c-12.895,0-22.845,5.017-29.846,15.05c-7.003,10.036-10.546,24.744-10.631,44.127v9.093
|
c-7.003-10.163-16.993-15.243-29.972-15.243c-12.895,0-22.845,5.017-29.846,15.05c-7.003,10.036-10.546,24.744-10.631,44.127v9.093
|
||||||
c0,19.043,3.5,33.817,10.503,44.319c7,10.504,17.079,15.755,30.229,15.755c12.893,0,22.799-5.059,29.715-15.178
|
c0,19.043,3.5,33.817,10.503,44.319c7,10.504,17.079,15.755,30.229,15.755c12.893,0,22.799-5.059,29.715-15.178
|
||||||
c6.917-10.119,10.418-24.868,10.504-44.255L727.873,749.701L727.873,749.701z"/>
|
c6.917-10.119,10.418-24.868,10.504-44.255L727.873,749.701L727.873,749.701z'
|
||||||
<path d="M794.736,847.177V660.678h65.326c22.627,0,39.791,4.336,51.491,13.001c11.699,8.668,17.549,21.372,17.549,38.107
|
/>
|
||||||
|
<path
|
||||||
|
d='M794.736,847.177V660.678h65.326c22.627,0,39.791,4.336,51.491,13.001c11.699,8.668,17.549,21.372,17.549,38.107
|
||||||
c0,9.138-2.35,17.187-7.045,24.146c-4.697,6.961-11.23,12.062-19.597,15.307c9.562,2.39,17.1,7.216,22.607,14.474
|
c0,9.138-2.35,17.187-7.045,24.146c-4.697,6.961-11.23,12.062-19.597,15.307c9.562,2.39,17.1,7.216,22.607,14.474
|
||||||
c5.508,7.259,8.263,16.138,8.263,26.642c0,17.934-5.723,31.51-17.165,40.733c-11.446,9.223-27.754,13.919-48.93,14.089
|
c5.508,7.259,8.263,16.138,8.263,26.642c0,17.934-5.723,31.51-17.165,40.733c-11.446,9.223-27.754,13.919-48.93,14.089
|
||||||
L794.736,847.177L794.736,847.177z M833.162,738.813h28.437c19.383-0.341,29.076-8.069,29.076-23.186
|
L794.736,847.177L794.736,847.177z M833.162,738.813h28.437c19.383-0.341,29.076-8.069,29.076-23.186
|
||||||
c0-8.453-2.455-14.538-7.364-18.252c-4.913-3.714-12.662-5.572-23.248-5.572h-26.9V738.813L833.162,738.813z M833.162,765.968
|
c0-8.453-2.455-14.538-7.364-18.252c-4.913-3.714-12.662-5.572-23.248-5.572h-26.9V738.813L833.162,738.813z M833.162,765.968
|
||||||
v50.341h32.919c9.051,0,16.118-2.155,21.198-6.469c5.08-4.313,7.621-10.269,7.621-17.868c0-17.078-8.838-25.746-26.514-26.003
|
v50.341h32.919c9.051,0,16.118-2.155,21.198-6.469c5.08-4.313,7.621-10.269,7.621-17.868c0-17.078-8.838-25.746-26.514-26.003
|
||||||
L833.162,765.968L833.162,765.968z"/>
|
L833.162,765.968L833.162,765.968z'
|
||||||
<path d="M1115.343,758.155c0,18.361-3.245,34.457-9.734,48.289c-6.492,13.834-15.776,24.51-27.858,32.022
|
/>
|
||||||
|
<path
|
||||||
|
d='M1115.343,758.155c0,18.361-3.245,34.457-9.734,48.289c-6.492,13.834-15.776,24.51-27.858,32.022
|
||||||
c-12.085,7.516-25.94,11.273-41.567,11.273c-15.457,0-29.246-3.715-41.37-11.145c-12.127-7.429-21.521-18.039-28.182-31.831
|
c-12.085,7.516-25.94,11.273-41.567,11.273c-15.457,0-29.246-3.715-41.37-11.145c-12.127-7.429-21.521-18.039-28.182-31.831
|
||||||
c-6.66-13.789-10.035-29.653-10.119-47.584v-9.223c0-18.358,3.309-34.521,9.928-48.481c6.616-13.962,15.966-24.678,28.051-32.15
|
c-6.66-13.789-10.035-29.653-10.119-47.584v-9.223c0-18.358,3.309-34.521,9.928-48.481c6.616-13.962,15.966-24.678,28.051-32.15
|
||||||
c12.081-7.471,25.894-11.207,41.436-11.207s29.354,3.735,41.439,11.207c12.079,7.473,21.432,18.188,28.05,32.15
|
c12.081-7.471,25.894-11.207,41.436-11.207s29.354,3.735,41.439,11.207c12.079,7.473,21.432,18.188,28.05,32.15
|
||||||
c6.616,13.961,9.926,30.081,9.926,48.354v8.325H1115.343z M1076.405,749.701c0-19.553-3.504-34.411-10.505-44.574
|
c6.616,13.961,9.926,30.081,9.926,48.354v8.325H1115.343z M1076.405,749.701c0-19.553-3.504-34.411-10.505-44.574
|
||||||
s-16.992-15.243-29.973-15.243c-12.895,0-22.844,5.017-29.845,15.05c-7.004,10.036-10.548,24.744-10.632,44.127v9.093
|
s-16.992-15.243-29.973-15.243c-12.895,0-22.844,5.017-29.845,15.05c-7.004,10.036-10.548,24.744-10.632,44.127v9.093
|
||||||
c0,19.043,3.501,33.817,10.503,44.319c7.002,10.504,17.079,15.755,30.229,15.755c12.896,0,22.802-5.059,29.717-15.178
|
c0,19.043,3.501,33.817,10.503,44.319c7.002,10.504,17.079,15.755,30.229,15.755c12.896,0,22.802-5.059,29.717-15.178
|
||||||
c6.918-10.119,10.419-24.868,10.505-44.255L1076.405,749.701L1076.405,749.701z"/>
|
c6.918-10.119,10.419-24.868,10.505-44.255L1076.405,749.701L1076.405,749.701z'
|
||||||
<path d="M1239.975,798.248c0-7.258-2.563-12.829-7.686-16.717c-5.123-3.884-14.346-7.982-27.666-12.296
|
/>
|
||||||
|
<path
|
||||||
|
d='M1239.975,798.248c0-7.258-2.563-12.829-7.686-16.717c-5.123-3.884-14.346-7.982-27.666-12.296
|
||||||
c-13.323-4.312-23.869-8.561-31.64-12.744c-21.178-11.443-31.766-26.855-31.766-46.241c0-10.075,2.838-19.064,8.517-26.963
|
c-13.323-4.312-23.869-8.561-31.64-12.744c-21.178-11.443-31.766-26.855-31.766-46.241c0-10.075,2.838-19.064,8.517-26.963
|
||||||
c5.679-7.897,13.835-14.067,24.466-18.508c10.631-4.439,22.563-6.66,35.801-6.66c13.323,0,25.191,2.412,35.609,7.236
|
c5.679-7.897,13.835-14.067,24.466-18.508c10.631-4.439,22.563-6.66,35.801-6.66c13.323,0,25.191,2.412,35.609,7.236
|
||||||
c10.417,4.826,18.509,11.636,24.272,20.43c5.765,8.796,8.647,18.787,8.647,29.973h-38.426c0-8.536-2.692-15.177-8.071-19.917
|
c10.417,4.826,18.509,11.636,24.272,20.43c5.765,8.796,8.647,18.787,8.647,29.973h-38.426c0-8.536-2.692-15.177-8.071-19.917
|
||||||
@ -57,11 +74,15 @@ export default function RoboSatsTextIcon(props) {
|
|||||||
c0,6.063,3.053,11.143,9.16,15.241c6.104,4.099,15.091,7.941,26.962,11.528c21.859,6.577,37.786,14.73,47.776,24.465
|
c0,6.063,3.053,11.143,9.16,15.241c6.104,4.099,15.091,7.941,26.962,11.528c21.859,6.577,37.786,14.73,47.776,24.465
|
||||||
c9.991,9.735,14.987,21.861,14.987,36.377c0,16.139-6.106,28.8-18.317,37.979c-12.212,9.181-28.649,13.771-49.313,13.771
|
c9.991,9.735,14.987,21.861,14.987,36.377c0,16.139-6.106,28.8-18.317,37.979c-12.212,9.181-28.649,13.771-49.313,13.771
|
||||||
c-14.347,0-27.411-2.626-39.195-7.878s-20.773-12.444-26.964-21.583c-6.192-9.136-9.286-19.725-9.286-31.767h38.556
|
c-14.347,0-27.411-2.626-39.195-7.878s-20.773-12.444-26.964-21.583c-6.192-9.136-9.286-19.725-9.286-31.767h38.556
|
||||||
c0,20.581,12.296,30.87,36.891,30.87c9.136,0,16.269-1.858,21.391-5.573C1237.414,810.097,1239.975,804.907,1239.975,798.248z"/>
|
c0,20.581,12.296,30.87,36.891,30.87c9.136,0,16.269-1.858,21.391-5.573C1237.414,810.097,1239.975,804.907,1239.975,798.248z'
|
||||||
<path d="M1409.822,808.75h-67.376l-12.809,38.427h-40.861l69.424-186.498h35.611l69.809,186.498h-40.861L1409.822,808.75z
|
/>
|
||||||
M1352.822,777.625h46.624l-23.44-69.809L1352.822,777.625z"/>
|
<path
|
||||||
<path d="M1606.055,691.805h-57.127v155.372h-38.429V691.805h-56.358v-31.126h151.914V691.805L1606.055,691.805z"/>
|
d='M1409.822,808.75h-67.376l-12.809,38.427h-40.861l69.424-186.498h35.611l69.809,186.498h-40.861L1409.822,808.75z
|
||||||
<path d="M1722.617,798.248c0-7.258-2.563-12.829-7.687-16.717c-5.123-3.884-14.346-7.982-27.666-12.296
|
M1352.822,777.625h46.624l-23.44-69.809L1352.822,777.625z'
|
||||||
|
/>
|
||||||
|
<path d='M1606.055,691.805h-57.127v155.372h-38.429V691.805h-56.358v-31.126h151.914V691.805L1606.055,691.805z' />
|
||||||
|
<path
|
||||||
|
d='M1722.617,798.248c0-7.258-2.563-12.829-7.687-16.717c-5.123-3.884-14.346-7.982-27.666-12.296
|
||||||
c-13.323-4.312-23.87-8.561-31.639-12.744c-21.179-11.443-31.767-26.855-31.767-46.241c0-10.075,2.837-19.064,8.517-26.963
|
c-13.323-4.312-23.87-8.561-31.639-12.744c-21.179-11.443-31.767-26.855-31.767-46.241c0-10.075,2.837-19.064,8.517-26.963
|
||||||
c5.679-7.897,13.835-14.067,24.466-18.508c10.632-4.439,22.563-6.66,35.801-6.66c13.323,0,25.19,2.412,35.609,7.236
|
c5.679-7.897,13.835-14.067,24.466-18.508c10.632-4.439,22.563-6.66,35.801-6.66c13.323,0,25.19,2.412,35.609,7.236
|
||||||
c10.417,4.826,18.509,11.636,24.273,20.43c5.764,8.796,8.646,18.787,8.646,29.973h-38.426c0-8.536-2.692-15.177-8.072-19.917
|
c10.417,4.826,18.509,11.636,24.273,20.43c5.764,8.796,8.646,18.787,8.646,29.973h-38.426c0-8.536-2.692-15.177-8.072-19.917
|
||||||
@ -69,8 +90,9 @@ export default function RoboSatsTextIcon(props) {
|
|||||||
c0,6.063,3.053,11.143,9.16,15.241c6.104,4.099,15.091,7.941,26.962,11.528c21.858,6.577,37.786,14.73,47.776,24.465
|
c0,6.063,3.053,11.143,9.16,15.241c6.104,4.099,15.091,7.941,26.962,11.528c21.858,6.577,37.786,14.73,47.776,24.465
|
||||||
c9.991,9.735,14.987,21.861,14.987,36.377c0,16.139-6.106,28.8-18.317,37.979c-12.212,9.181-28.648,13.771-49.313,13.771
|
c9.991,9.735,14.987,21.861,14.987,36.377c0,16.139-6.106,28.8-18.317,37.979c-12.212,9.181-28.648,13.771-49.313,13.771
|
||||||
c-14.346,0-27.411-2.626-39.195-7.878s-20.774-12.444-26.964-21.583c-6.192-9.136-9.286-19.725-9.286-31.767h38.556
|
c-14.346,0-27.411-2.626-39.195-7.878s-20.774-12.444-26.964-21.583c-6.192-9.136-9.286-19.725-9.286-31.767h38.556
|
||||||
c0,20.581,12.296,30.87,36.891,30.87c9.136,0,16.268-1.858,21.391-5.573C1720.055,810.097,1722.617,804.907,1722.617,798.248z"/>
|
c0,20.581,12.296,30.87,36.891,30.87c9.136,0,16.268-1.858,21.391-5.573C1720.055,810.097,1722.617,804.907,1722.617,798.248z'
|
||||||
|
/>
|
||||||
</g>
|
</g>
|
||||||
</SvgIcon>
|
</SvgIcon>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,50 +1,112 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import { SvgIcon } from "@mui/material"
|
import { SvgIcon } from '@mui/material';
|
||||||
|
|
||||||
export default function SellSatsIcon(props) {
|
export default function SellSatsIcon(props) {
|
||||||
return (
|
return (
|
||||||
<SvgIcon sx={props.sx} color={props.color} x="0px" y="0px" viewBox="0 0 300 300">
|
<SvgIcon sx={props.sx} color={props.color} x='0px' y='0px' viewBox='0 0 300 300'>
|
||||||
<g>
|
<g>
|
||||||
<polygon fill={props.color} points="121.609,110.04 125.066,113.125 130.511,117.982 133.404,120.564 138.846,125.421 141.355,127.66
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
|
points='121.609,110.04 125.066,113.125 130.511,117.982 133.404,120.564 138.846,125.421 141.355,127.66
|
||||||
142.283,128.49 147.107,123.082 144.288,120.564 138.846,115.709 135.951,113.125 130.509,108.27 127.053,105.184
|
142.283,128.49 147.107,123.082 144.288,120.564 138.846,115.709 135.951,113.125 130.509,108.27 127.053,105.184
|
||||||
122.057,100.729 119.174,102.5 115.611,104.689 116.166,105.184 "/>
|
122.057,100.729 119.174,102.5 115.611,104.689 116.166,105.184 '
|
||||||
<polygon fill={props.color} points="133.966,105.184 139.412,110.04 142.305,112.623 147.744,117.479 149.48,119.025 150.408,119.855
|
/>
|
||||||
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
|
points='133.966,105.184 139.412,110.04 142.305,112.623 147.744,117.479 149.48,119.025 150.408,119.855
|
||||||
155.234,114.449 153.188,112.623 147.744,107.768 144.854,105.186 139.41,100.328 135.951,97.244 132.6,94.252 126.15,98.213
|
155.234,114.449 153.188,112.623 147.744,107.768 144.854,105.186 139.41,100.328 135.951,97.244 132.6,94.252 126.15,98.213
|
||||||
130.509,102.1 "/>
|
130.509,102.1 '
|
||||||
<polygon fill={props.color} points="142.305,97.745 147.747,102.602 150.643,105.184 156.084,110.04 157.986,111.74 162.811,106.332
|
/>
|
||||||
161.523,105.184 156.08,100.328 153.188,97.746 147.744,92.891 144.288,89.805 142.473,88.184 136.027,92.146 138.846,94.66 "/>
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
<rect x="119.966" y="117.668" transform="matrix(0.7405 0.672 -0.672 0.7405 114.3002 -51.0573)" fill={props.color} width="6.611" height="9.654"/>
|
points='142.305,97.745 147.747,102.602 150.643,105.184 156.084,110.04 157.986,111.74 162.811,106.332
|
||||||
<polygon fill={props.color} points="158.871,88.123 152.965,84.797 149.123,89.025 154.02,93.467 "/>
|
161.523,105.184 156.08,100.328 153.188,97.746 147.744,92.891 144.288,89.805 142.473,88.184 136.027,92.146 138.846,94.66 '
|
||||||
<polygon fill={props.color} points="113.039,242.962 110.145,240.379 104.702,235.523 101.244,232.438 95.801,227.582 94.551,226.466
|
/>
|
||||||
|
|
||||||
|
<rect
|
||||||
|
x='119.966'
|
||||||
|
y='117.668'
|
||||||
|
transform='matrix(0.7405 0.672 -0.672 0.7405 114.3002 -51.0573)'
|
||||||
|
fill={props.color}
|
||||||
|
width='6.611'
|
||||||
|
height='9.654'
|
||||||
|
/>
|
||||||
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
|
points='158.871,88.123 152.965,84.797 149.123,89.025 154.02,93.467 '
|
||||||
|
/>
|
||||||
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
|
points='113.039,242.962 110.145,240.379 104.702,235.523 101.244,232.438 95.801,227.582 94.551,226.466
|
||||||
89.729,231.874 90.357,232.438 95.801,237.295 99.258,240.379 104.702,245.236 107.598,247.818 113.037,252.674 115.547,254.914
|
89.729,231.874 90.357,232.438 95.801,237.295 99.258,240.379 104.702,245.236 107.598,247.818 113.037,252.674 115.547,254.914
|
||||||
116.475,255.744 121.305,250.335 118.48,247.818 "/>
|
116.475,255.744 121.305,250.335 118.48,247.818 '
|
||||||
<polygon fill={props.color} points="121.938,235.021 119.046,232.438 113.602,227.582 110.145,224.497 104.702,219.641
|
/>
|
||||||
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
|
points='121.938,235.021 119.046,232.438 113.602,227.582 110.145,224.497 104.702,219.641
|
||||||
103.604,218.66 102.675,217.834 97.854,223.24 99.258,224.497 104.702,229.352 108.159,232.438 113.602,237.295 116.495,239.876
|
103.604,218.66 102.675,217.834 97.854,223.24 99.258,224.497 104.702,229.352 108.159,232.438 113.602,237.295 116.495,239.876
|
||||||
121.938,244.732 123.672,246.279 124.604,247.109 129.428,241.701 127.382,239.876 "/>
|
121.938,244.732 123.672,246.279 124.604,247.109 129.428,241.701 127.382,239.876 '
|
||||||
<polygon fill={props.color} points="130.277,227.582 127.382,225 121.938,220.145 118.48,217.059 113.038,212.202 111.182,210.544
|
/>
|
||||||
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
|
points='130.277,227.582 127.382,225 121.938,220.145 118.48,217.059 113.038,212.202 111.182,210.544
|
||||||
110.253,209.718 105.43,215.125 107.598,217.059 113.038,221.915 116.495,225 121.938,229.855 124.833,232.438 130.277,237.295
|
110.253,209.718 105.43,215.125 107.598,217.059 113.038,221.915 116.495,225 121.938,229.855 124.833,232.438 130.277,237.295
|
||||||
132.18,238.994 137.002,233.585 135.718,232.438 "/>
|
132.18,238.994 137.002,233.585 135.718,232.438 '
|
||||||
|
/>
|
||||||
<rect x="94.143" y="244.919" transform="matrix(0.7403 0.6723 -0.6723 0.7403 193.2158 -0.6485)" fill={props.color} width="6.609" height="9.657"/>
|
|
||||||
<polygon fill={props.color} points="134.702,213.575 129.807,209.133 123.316,216.279 128.211,220.721 "/>
|
<rect
|
||||||
<polygon fill={props.color} points="211.316,197.4 212.245,198.23 217.073,192.823 194.257,172.467 190.32,168.954 185.497,174.359
|
x='94.143'
|
||||||
187.4,176.062 "/>
|
y='244.919'
|
||||||
<polygon fill={props.color} points="219.443,188.768 220.369,189.598 225.197,184.189 205.331,166.463 199.373,161.146
|
transform='matrix(0.7403 0.6723 -0.6723 0.7403 193.2158 -0.6485)'
|
||||||
198.447,160.32 193.622,165.729 198.58,170.152 "/>
|
fill={props.color}
|
||||||
<polygon fill={props.color} points="227.951,181.48 232.771,176.072 215.531,160.689 207.816,153.805 206.949,153.032
|
width='6.609'
|
||||||
206.021,152.205 201.341,157.452 201.198,157.611 208.893,164.475 "/>
|
height='9.657'
|
||||||
|
/>
|
||||||
<rect x="189.921" y="187.4" transform="matrix(0.7405 0.6721 -0.6721 0.7405 179.3349 -79.9756)" fill={props.color} width="6.609" height="9.655"/>
|
<polygon
|
||||||
<polygon fill={props.color} points="230.471,156.062 227.62,153.475 225.578,151.619 219.378,158.445 219.086,158.766 223.98,163.208
|
fill={props.color}
|
||||||
"/>
|
points='134.702,213.575 129.807,209.133 123.316,216.279 128.211,220.721 '
|
||||||
<path fill={props.color} d="M112.534,187.282c-7.511,0-14.995,1.878-21.647,5.43c-10.848,5.793-18.796,15.479-22.379,27.277
|
/>
|
||||||
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
|
points='211.316,197.4 212.245,198.23 217.073,192.823 194.257,172.467 190.32,168.954 185.497,174.359
|
||||||
|
187.4,176.062 '
|
||||||
|
/>
|
||||||
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
|
points='219.443,188.768 220.369,189.598 225.197,184.189 205.331,166.463 199.373,161.146
|
||||||
|
198.447,160.32 193.622,165.729 198.58,170.152 '
|
||||||
|
/>
|
||||||
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
|
points='227.951,181.48 232.771,176.072 215.531,160.689 207.816,153.805 206.949,153.032
|
||||||
|
206.021,152.205 201.341,157.452 201.198,157.611 208.893,164.475 '
|
||||||
|
/>
|
||||||
|
|
||||||
|
<rect
|
||||||
|
x='189.921'
|
||||||
|
y='187.4'
|
||||||
|
transform='matrix(0.7405 0.6721 -0.6721 0.7405 179.3349 -79.9756)'
|
||||||
|
fill={props.color}
|
||||||
|
width='6.609'
|
||||||
|
height='9.655'
|
||||||
|
/>
|
||||||
|
<polygon
|
||||||
|
fill={props.color}
|
||||||
|
points='230.471,156.062 227.62,153.475 225.578,151.619 219.378,158.445 219.086,158.766 223.98,163.208
|
||||||
|
'
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill={props.color}
|
||||||
|
d='M112.534,187.282c-7.511,0-14.995,1.878-21.647,5.43c-10.848,5.793-18.796,15.479-22.379,27.277
|
||||||
c-3.583,11.796-2.365,24.266,3.426,35.112c8.033,15.037,23.646,24.379,40.742,24.379c7.51,0,14.996-1.877,21.648-5.431
|
c-3.583,11.796-2.365,24.266,3.426,35.112c8.033,15.037,23.646,24.379,40.742,24.379c7.51,0,14.996-1.877,21.648-5.431
|
||||||
c10.847-5.793,18.794-15.479,22.377-27.274c3.583-11.797,2.365-24.267-3.426-35.113
|
c10.847-5.793,18.794-15.479,22.377-27.274c3.583-11.797,2.365-24.267-3.426-35.113
|
||||||
C145.245,196.624,129.635,187.282,112.534,187.282z M128.768,263.645c-16.688,8.912-37.514,2.588-46.43-14.099
|
C145.245,196.624,129.635,187.282,112.534,187.282z M128.768,263.645c-16.688,8.912-37.514,2.588-46.43-14.099
|
||||||
c-8.908-16.688-2.584-37.517,14.104-46.428c16.688-8.913,37.519-2.586,46.432,14.1
|
c-8.908-16.688-2.584-37.517,14.104-46.428c16.688-8.913,37.519-2.586,46.432,14.1
|
||||||
C151.781,233.908,145.456,254.732,128.768,263.645z"/>
|
C151.781,233.908,145.456,254.732,128.768,263.645z'
|
||||||
<path fill={props.color} d="M52.191,144.639c6.326,5.757,17.865,13.457,34.295,22.881c18.544,10.64,43.998,23.457,59.836,27.527
|
/>
|
||||||
|
<path
|
||||||
|
fill={props.color}
|
||||||
|
d='M52.191,144.639c6.326,5.757,17.865,13.457,34.295,22.881c18.544,10.64,43.998,23.457,59.836,27.527
|
||||||
c0.785,0.199,1.621,0.301,2.484,0.301c1.916,0,5.619-0.547,15.812-4.947c0.823,2.479,1.856,4.886,3.086,7.188
|
c0.785,0.199,1.621,0.301,2.484,0.301c1.916,0,5.619-0.547,15.812-4.947c0.823,2.479,1.856,4.886,3.086,7.188
|
||||||
c8.032,15.037,23.644,24.379,40.743,24.379c7.509,0,14.994-1.878,21.646-5.43c10.847-5.792,18.796-15.478,22.378-27.274
|
c8.032,15.037,23.644,24.379,40.743,24.379c7.509,0,14.994-1.878,21.646-5.43c10.847-5.792,18.796-15.478,22.378-27.274
|
||||||
c3.583-11.798,2.365-24.268-3.428-35.113c-1.488-2.787-3.262-5.414-5.295-7.842c3.117-2.348,5.279-4.3,6.706-6.043
|
c3.583-11.798,2.365-24.268-3.428-35.113c-1.488-2.787-3.262-5.414-5.295-7.842c3.117-2.348,5.279-4.3,6.706-6.043
|
||||||
@ -61,12 +123,16 @@ export default function SellSatsIcon(props) {
|
|||||||
c8.911,16.687,2.588,37.511-14.101,46.422c-16.688,8.914-37.517,2.588-46.431-14.101c-1.646-3.086-2.771-6.316-3.406-9.586
|
c8.911,16.687,2.588,37.511-14.101,46.422c-16.688,8.914-37.517,2.588-46.431-14.101c-1.646-3.086-2.771-6.316-3.406-9.586
|
||||||
C174.003,178.857,173.9,175.221,174.344,171.672z M240.285,125.102l-34.512-20.586l34.512-60.934V125.102z M197.343,99.484
|
C174.003,178.857,173.9,175.221,174.344,171.672z M240.285,125.102l-34.512-20.586l34.512-60.934V125.102z M197.343,99.484
|
||||||
l-47.237-28.183l-46.689,28.232l-37.43-66.089c0.445-0.066,0.896-0.113,1.357-0.113h163.938c1.125,0,2.196,0.216,3.19,0.595
|
l-47.237-28.183l-46.689,28.232l-37.43-66.089c0.445-0.066,0.896-0.113,1.357-0.113h163.938c1.125,0,2.196,0.216,3.19,0.595
|
||||||
L197.343,99.484z"/>
|
L197.343,99.484z'
|
||||||
<path fill={props.color} d="M30.079,300H269.92c16.587,0,30.08-13.494,30.08-30.08V30.08C300,13.494,286.507,0,269.92,0H30.079
|
/>
|
||||||
|
<path
|
||||||
|
fill={props.color}
|
||||||
|
d='M30.079,300H269.92c16.587,0,30.08-13.494,30.08-30.08V30.08C300,13.494,286.507,0,269.92,0H30.079
|
||||||
C13.494,0,0,13.494,0,30.08v239.84C0,286.506,13.494,300,30.079,300z M15.587,30.08c0-7.992,6.501-14.494,14.492-14.494H269.92
|
C13.494,0,0,13.494,0,30.08v239.84C0,286.506,13.494,300,30.079,300z M15.587,30.08c0-7.992,6.501-14.494,14.492-14.494H269.92
|
||||||
c7.992,0,14.494,6.502,14.494,14.494v239.84c0,7.992-6.502,14.494-14.494,14.494H30.079c-7.991,0-14.492-6.502-14.492-14.494
|
c7.992,0,14.494,6.502,14.494,14.494v239.84c0,7.992-6.502,14.494-14.494,14.494H30.079c-7.991,0-14.492-6.502-14.492-14.494
|
||||||
V30.08z"/>
|
V30.08z'
|
||||||
</g>
|
/>
|
||||||
</SvgIcon>
|
</g>
|
||||||
);
|
</SvgIcon>
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import { SvgIcon } from "@mui/material"
|
import { SvgIcon } from '@mui/material';
|
||||||
|
|
||||||
export default function SellSatsCheckedIcon(props) {
|
export default function SellSatsCheckedIcon(props) {
|
||||||
return (
|
return (
|
||||||
<SvgIcon sx={props.sx} color={props.color} x="0px" y="0px" viewBox="0 0 300 300">
|
<SvgIcon sx={props.sx} color={props.color} x='0px' y='0px' viewBox='0 0 300 300'>
|
||||||
<g>
|
<g>
|
||||||
<polygon fill={props.color} points="240.285,125.102 240.285,43.582 205.773,104.516 "/>
|
<polygon fill={props.color} points='240.285,125.102 240.285,43.582 205.773,104.516 ' />
|
||||||
<path fill={props.color} d="M58.583,40.294c-0.151,0.657-0.24,1.34-0.24,2.042v84.453l36.673-22.176L58.583,40.294z"/>
|
<path
|
||||||
<path fill={props.color} d="M112.81,199.078c-5.534-0.042-11.153,1.255-16.368,4.04c-16.688,8.911-23.012,29.739-14.104,46.428
|
fill={props.color}
|
||||||
|
d='M58.583,40.294c-0.151,0.657-0.24,1.34-0.24,2.042v84.453l36.673-22.176L58.583,40.294z'
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill={props.color}
|
||||||
|
d='M112.81,199.078c-5.534-0.042-11.153,1.255-16.368,4.04c-16.688,8.911-23.012,29.739-14.104,46.428
|
||||||
c6.13,11.472,17.889,18.046,30.062,18.139c5.533,0.042,11.152-1.255,16.368-4.04c0.521-0.278,1.033-0.568,1.534-0.87
|
c6.13,11.472,17.889,18.046,30.062,18.139c5.533,0.042,11.152-1.255,16.368-4.04c0.521-0.278,1.033-0.568,1.534-0.87
|
||||||
c1.002-0.603,1.963-1.249,2.882-1.938c1.46-1.093,2.813-2.289,4.056-3.571c5.381-5.558,8.668-12.749,9.475-20.292
|
c1.002-0.603,1.963-1.249,2.882-1.938c1.46-1.093,2.813-2.289,4.056-3.571c5.381-5.558,8.668-12.749,9.475-20.292
|
||||||
c0.706-6.601-0.487-13.471-3.841-19.756C136.746,205.746,124.985,199.171,112.81,199.078z M129.807,209.133l4.895,4.442
|
c0.706-6.601-0.487-13.471-3.841-19.756C136.746,205.746,124.985,199.171,112.81,199.078z M129.807,209.133l4.895,4.442
|
||||||
@ -18,10 +23,16 @@ export default function SellSatsCheckedIcon(props) {
|
|||||||
l-1.404-1.257l4.821-5.406l0.001,0.001l0.928,0.825l1.098,0.98l5.443,4.856l3.457,3.085l5.444,4.855l2.892,2.584l5.444,4.854
|
l-1.404-1.257l4.821-5.406l0.001,0.001l0.928,0.825l1.098,0.98l5.443,4.856l3.457,3.085l5.444,4.855l2.892,2.584l5.444,4.854
|
||||||
l2.046,1.825L124.604,247.109z M132.18,238.994l-1.903-1.699l-5.444-4.857l-2.895-2.582L116.495,225l-3.457-3.085l-5.44-4.856
|
l2.046,1.825L124.604,247.109z M132.18,238.994l-1.903-1.699l-5.444-4.857l-2.895-2.582L116.495,225l-3.457-3.085l-5.44-4.856
|
||||||
l-2.168-1.934l4.823-5.407l0.929,0.826l1.856,1.658l5.442,4.856l3.458,3.086l4.854,4.33l0.589,0.525l2.895,2.582l5.441,4.855
|
l-2.168-1.934l4.823-5.407l0.929,0.826l1.856,1.658l5.442,4.856l3.458,3.086l4.854,4.33l0.589,0.525l2.895,2.582l5.441,4.855
|
||||||
l1.283,1.146l0.001,0.001L132.18,238.994z"/>
|
l1.283,1.146l0.001,0.001L132.18,238.994z'
|
||||||
<path fill={props.color} d="M103.417,99.533l46.689-28.232l47.237,28.183l10.278-18.148l26.851-47.409l0.001-0.001
|
/>
|
||||||
c-0.994-0.379-2.065-0.595-3.19-0.595H67.344c-0.461,0-0.912,0.047-1.357,0.113l0.002,0.003L103.417,99.533z"/>
|
<path
|
||||||
<path fill={props.color} d="M188.072,137.845c2.039-1.089,4.131-1.976,6.249-2.708c12.551-4.337,26.17-2.534,37.015,4.271l0.001,0
|
fill={props.color}
|
||||||
|
d='M103.417,99.533l46.689-28.232l47.237,28.183l10.278-18.148l26.851-47.409l0.001-0.001
|
||||||
|
c-0.994-0.379-2.065-0.595-3.19-0.595H67.344c-0.461,0-0.912,0.047-1.357,0.113l0.002,0.003L103.417,99.533z'
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill={props.color}
|
||||||
|
d='M188.072,137.845c2.039-1.089,4.131-1.976,6.249-2.708c12.551-4.337,26.17-2.534,37.015,4.271l0.001,0
|
||||||
c2.595-1.757,4.685-3.269,6.238-4.499l-56.337-33.61c0,0.001,0,0.003,0,0.004c1.895,17.026-6.509,34.3-22.518,42.847
|
c2.595-1.757,4.685-3.269,6.238-4.499l-56.337-33.61c0,0.001,0,0.003,0,0.004c1.895,17.026-6.509,34.3-22.518,42.847
|
||||||
c-6.553,3.5-13.612,5.129-20.564,5.076c-15.294-0.117-30.068-8.378-37.768-22.792c-1.731-3.242-3.001-6.613-3.84-10.029
|
c-6.553,3.5-13.612,5.129-20.564,5.076c-15.294-0.117-30.068-8.378-37.768-22.792c-1.731-3.242-3.001-6.613-3.84-10.029
|
||||||
l7.985-4.906l0.001,0c0.578,3.681,1.761,7.325,3.615,10.793c4.733,8.866,12.831,14.807,21.884,17.093
|
l7.985-4.906l0.001,0c0.578,3.681,1.761,7.325,3.615,10.793c4.733,8.866,12.831,14.807,21.884,17.093
|
||||||
@ -35,8 +46,11 @@ export default function SellSatsCheckedIcon(props) {
|
|||||||
M132.6,94.252l3.351,2.992l3.459,3.084l5.444,4.858l2.89,2.582l5.443,4.855l2.046,1.825l0.001,0.001l-4.826,5.406l-0.928-0.83
|
M132.6,94.252l3.351,2.992l3.459,3.084l5.444,4.858l2.89,2.582l5.443,4.855l2.046,1.825l0.001,0.001l-4.826,5.406l-0.928-0.83
|
||||||
l-1.736-1.546l-5.439-4.856l-2.893-2.583l-5.446-4.856l-3.457-3.084l-4.359-3.887L132.6,94.252z M119.174,102.5l2.883-1.771
|
l-1.736-1.546l-5.439-4.856l-2.893-2.583l-5.446-4.856l-3.457-3.084l-4.359-3.887L132.6,94.252z M119.174,102.5l2.883-1.771
|
||||||
l4.996,4.455l3.456,3.086l5.442,4.855l2.895,2.584l5.442,4.855l2.819,2.518l-4.824,5.408l-0.928-0.83l-2.509-2.239l-5.442-4.857
|
l4.996,4.455l3.456,3.086l5.442,4.855l2.895,2.584l5.442,4.855l2.819,2.518l-4.824,5.408l-0.928-0.83l-2.509-2.239l-5.442-4.857
|
||||||
l-2.893-2.582l-5.445-4.857l-3.457-3.085l-5.443-4.856l-0.553-0.493l-0.002-0.002L119.174,102.5z"/>
|
l-2.893-2.582l-5.445-4.857l-3.457-3.085l-5.443-4.856l-0.553-0.493l-0.002-0.002L119.174,102.5z'
|
||||||
<path fill={props.color} d="M231.82,150.836c-2.649-2.482-5.65-4.502-8.875-6.015c-9.465-4.428-20.827-4.506-30.732,0.785
|
/>
|
||||||
|
<path
|
||||||
|
fill={props.color}
|
||||||
|
d='M231.82,150.836c-2.649-2.482-5.65-4.502-8.875-6.015c-9.465-4.428-20.827-4.506-30.732,0.785
|
||||||
c-10.213,5.453-16.535,15.369-17.869,26.066c-0.119,0.951-0.191,1.909-0.23,2.87c-0.108,2.625,0.076,5.276,0.587,7.903
|
c-10.213,5.453-16.535,15.369-17.869,26.066c-0.119,0.951-0.191,1.909-0.23,2.87c-0.108,2.625,0.076,5.276,0.587,7.903
|
||||||
c0.635,3.271,1.76,6.5,3.405,9.587c8.914,16.688,29.744,23.015,46.432,14.101c10.432-5.569,16.812-15.792,17.956-26.751
|
c0.635,3.271,1.76,6.5,3.405,9.587c8.914,16.688,29.744,23.015,46.432,14.101c10.432-5.569,16.812-15.792,17.956-26.751
|
||||||
c0.686-6.574-0.514-13.413-3.854-19.671C236.818,156.305,234.497,153.338,231.82,150.836z M219.378,158.445l6.2-6.826l2.042,1.855
|
c0.686-6.574-0.514-13.413-3.854-19.671C236.818,156.305,234.497,153.338,231.82,150.836z M219.378,158.445l6.2-6.826l2.042,1.855
|
||||||
@ -44,8 +58,11 @@ export default function SellSatsCheckedIcon(props) {
|
|||||||
l1.473-1.623l4.895,4.442L197.446,192.499z M212.245,198.23l-0.929-0.83L187.4,176.062l-1.903-1.703l4.823-5.405l3.937,3.513
|
l1.473-1.623l4.895,4.442L197.446,192.499z M212.245,198.23l-0.929-0.83L187.4,176.062l-1.903-1.703l4.823-5.405l3.937,3.513
|
||||||
l22.816,20.356L212.245,198.23z M220.369,189.598l-0.926-0.83l-20.863-18.615l-4.958-4.424l4.825-5.408l0.926,0.826l5.958,5.316
|
l22.816,20.356L212.245,198.23z M220.369,189.598l-0.926-0.83l-20.863-18.615l-4.958-4.424l4.825-5.408l0.926,0.826l5.958,5.316
|
||||||
l19.866,17.727L220.369,189.598z M227.951,181.48l-19.059-17.006l-7.694-6.863l0.143-0.159l4.681-5.247l0.928,0.827l0.867,0.772
|
l19.866,17.727L220.369,189.598z M227.951,181.48l-19.059-17.006l-7.694-6.863l0.143-0.159l4.681-5.247l0.928,0.827l0.867,0.772
|
||||||
l7.715,6.885l17.24,15.383L227.951,181.48z"/>
|
l7.715,6.885l17.24,15.383L227.951,181.48z'
|
||||||
<path fill={props.color} d="M269.92,0H30.079C13.494,0,0,13.494,0,30.08v239.84C0,286.506,13.494,300,30.079,300H269.92
|
/>
|
||||||
|
<path
|
||||||
|
fill={props.color}
|
||||||
|
d='M269.92,0H30.079C13.494,0,0,13.494,0,30.08v239.84C0,286.506,13.494,300,30.079,300H269.92
|
||||||
c16.587,0,30.08-13.494,30.08-30.08V30.08C300,13.494,286.507,0,269.92,0z M157.316,244.557c-0.187,0.741-0.392,1.481-0.615,2.219
|
c16.587,0,30.08-13.494,30.08-30.08V30.08C300,13.494,286.507,0,269.92,0z M157.316,244.557c-0.187,0.741-0.392,1.481-0.615,2.219
|
||||||
c-3.583,11.795-11.53,21.48-22.377,27.273c-6.652,3.555-14.138,5.432-21.648,5.432c-17.096,0-32.709-9.342-40.742-24.379
|
c-3.583,11.795-11.53,21.48-22.377,27.273c-6.652,3.555-14.138,5.432-21.648,5.432c-17.096,0-32.709-9.342-40.742-24.379
|
||||||
c-3.62-6.779-5.453-14.192-5.444-21.679c0.004-2.995,0.302-6.001,0.898-8.983c0.298-1.491,0.671-2.977,1.119-4.451
|
c-3.62-6.779-5.453-14.192-5.444-21.679c0.004-2.995,0.302-6.001,0.898-8.983c0.298-1.491,0.671-2.977,1.119-4.451
|
||||||
@ -57,8 +74,9 @@ export default function SellSatsCheckedIcon(props) {
|
|||||||
c-16.43-9.424-27.969-17.124-34.295-22.88c-1.155-1.052-2.111-2.014-2.902-2.899c-3.426-3.833-3.765-6.229-3.761-8.206V42.337
|
c-16.43-9.424-27.969-17.124-34.295-22.88c-1.155-1.052-2.111-2.014-2.902-2.899c-3.426-3.833-3.765-6.229-3.761-8.206V42.337
|
||||||
c0-12.027,9.789-21.814,21.817-21.814l163.939-0.005c5.638,0,10.784,2.151,14.66,5.675c4.393,3.994,7.155,9.752,7.155,16.143
|
c0-12.027,9.789-21.814,21.817-21.814l163.939-0.005c5.638,0,10.784,2.151,14.66,5.675c4.393,3.994,7.155,9.752,7.155,16.143
|
||||||
v91.201c0,2.378-0.841,4.516-2.646,6.729c-1.427,1.743-3.589,3.695-6.706,6.043c2.033,2.428,3.807,5.055,5.295,7.841
|
v91.201c0,2.378-0.841,4.516-2.646,6.729c-1.427,1.743-3.589,3.695-6.706,6.043c2.033,2.428,3.807,5.055,5.295,7.841
|
||||||
C254.836,164.996,256.054,177.466,252.471,189.264z"/>
|
C254.836,164.996,256.054,177.466,252.471,189.264z'
|
||||||
|
/>
|
||||||
</g>
|
</g>
|
||||||
</SvgIcon>
|
</SvgIcon>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import { SvgIcon } from "@mui/material"
|
import { SvgIcon } from '@mui/material';
|
||||||
|
|
||||||
export default function SendReceiveIcon(props) {
|
export default function SendReceiveIcon(props) {
|
||||||
return (
|
return (
|
||||||
<SvgIcon sx={props.sx} color={props.color} x="0px" y="0px" viewBox="0 0 300 300">
|
<SvgIcon sx={props.sx} color={props.color} x='0px' y='0px' viewBox='0 0 300 300'>
|
||||||
<g>
|
<g>
|
||||||
<path fill={props.color} d="M150.021,2.579C68.341,2.579,2.127,68.793,2.127,150.472c0,81.682,66.214,147.895,147.895,147.895
|
<path
|
||||||
|
fill={props.color}
|
||||||
|
d='M150.021,2.579C68.341,2.579,2.127,68.793,2.127,150.472c0,81.682,66.214,147.895,147.895,147.895
|
||||||
c81.676,0,147.89-66.213,147.89-147.895C297.911,68.793,231.697,2.579,150.021,2.579z M99.195,73.557
|
c81.676,0,147.89-66.213,147.89-147.895C297.911,68.793,231.697,2.579,150.021,2.579z M99.195,73.557
|
||||||
c0,0,60.301,60.307,60.306,60.309c4.899,4.895,11.188,13.849,8.663,21.061c-1.835,5.236-6.053,9.546-9.893,13.383
|
c0,0,60.301,60.307,60.306,60.309c4.899,4.895,11.188,13.849,8.663,21.061c-1.835,5.236-6.053,9.546-9.893,13.383
|
||||||
c-0.091,0.093-59.076,59.078-59.076,59.078c-6.26,6.26-16.406,6.26-22.665,0c-6.261-6.256-6.261-16.406,0-22.665l54.247-54.25
|
c-0.091,0.093-59.076,59.078-59.076,59.078c-6.26,6.26-16.406,6.26-22.665,0c-6.261-6.256-6.261-16.406,0-22.665l54.247-54.25
|
||||||
@ -13,8 +15,9 @@ export default function SendReceiveIcon(props) {
|
|||||||
z M146.365,73.557c3.125-3.128,7.23-4.693,11.33-4.693c4.101,0,8.204,1.565,11.335,4.693c0,0,60.303,60.307,60.308,60.309
|
z M146.365,73.557c3.125-3.128,7.23-4.693,11.33-4.693c4.101,0,8.204,1.565,11.335,4.693c0,0,60.303,60.307,60.308,60.309
|
||||||
c4.895,4.894,11.188,13.849,8.659,21.061c-1.832,5.236-6.05,9.546-9.889,13.383c-0.092,0.094-59.078,59.078-59.078,59.078
|
c4.895,4.894,11.188,13.849,8.659,21.061c-1.832,5.236-6.05,9.546-9.889,13.383c-0.092,0.094-59.078,59.078-59.078,59.078
|
||||||
c-6.256,6.26-16.405,6.26-22.665,0c-6.258-6.256-6.258-16.406,0-22.665l54.246-54.25l-54.246-54.25
|
c-6.256,6.26-16.405,6.26-22.665,0c-6.258-6.256-6.258-16.406,0-22.665l54.246-54.25l-54.246-54.25
|
||||||
C140.107,89.966,140.107,79.818,146.365,73.557z"/>
|
C140.107,89.966,140.107,79.818,146.365,73.557z'
|
||||||
</g>
|
/>
|
||||||
</SvgIcon>
|
</g>
|
||||||
);
|
</SvgIcon>
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import { SvgIcon } from "@mui/material"
|
import { SvgIcon } from '@mui/material';
|
||||||
|
|
||||||
export default function UserNinjaIcon(props) {
|
export default function UserNinjaIcon(props) {
|
||||||
return (
|
return (
|
||||||
<SvgIcon {...props} x="0px" y="0px" viewBox="0 0 512 512">
|
<SvgIcon {...props} x='0px' y='0px' viewBox='0 0 512 512'>
|
||||||
<path d="M64 192c27.25 0 51.75-11.5 69.25-29.75c15 54 64 93.75 122.8 93.75c70.75 0 127.1-57.25 127.1-128s-57.25-128-127.1-128c-50.38 0-93.63 29.38-114.5 71.75C124.1 47.75 96 32 64 32c0 33.37 17.12 62.75 43.13 80C81.13 129.3 64 158.6 64 192zM208 96h95.1C321.7 96 336 110.3 336 128h-160C176 110.3 190.3 96 208 96zM337.8 306.9L256 416L174.2 306.9C93.36 321.6 32 392.2 32 477.3c0 19.14 15.52 34.67 34.66 34.67H445.3c19.14 0 34.66-15.52 34.66-34.67C480 392.2 418.6 321.6 337.8 306.9z"/>
|
<path d='M64 192c27.25 0 51.75-11.5 69.25-29.75c15 54 64 93.75 122.8 93.75c70.75 0 127.1-57.25 127.1-128s-57.25-128-127.1-128c-50.38 0-93.63 29.38-114.5 71.75C124.1 47.75 96 32 64 32c0 33.37 17.12 62.75 43.13 80C81.13 129.3 64 158.6 64 192zM208 96h95.1C321.7 96 336 110.3 336 128h-160C176 110.3 190.3 96 208 96zM337.8 306.9L256 416L174.2 306.9C93.36 321.6 32 392.2 32 477.3c0 19.14 15.52 34.67 34.66 34.67H445.3c19.14 0 34.66-15.52 34.66-34.67C480 392.2 418.6 321.6 337.8 306.9z' />
|
||||||
</SvgIcon>
|
</SvgIcon>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
export { default as AmbossIcon } from "./Amboss";
|
export { default as AmbossIcon } from './Amboss';
|
||||||
export { default as BitcoinIcon } from "./Bitcoin";
|
export { default as BitcoinIcon } from './Bitcoin';
|
||||||
export { default as BitcoinSignIcon } from "./BitcoinSign";
|
export { default as BitcoinSignIcon } from './BitcoinSign';
|
||||||
export { default as BuySatsIcon } from "./BuySats";
|
export { default as BuySatsIcon } from './BuySats';
|
||||||
export { default as BuySatsCheckedIcon } from "./BuySatsChecked";
|
export { default as BuySatsCheckedIcon } from './BuySatsChecked';
|
||||||
export { default as EarthIcon } from "./Earth";
|
export { default as EarthIcon } from './Earth';
|
||||||
export { default as GoldIcon } from "./Gold";
|
export { default as GoldIcon } from './Gold';
|
||||||
export { default as NewTabIcon } from "./NewTab";
|
export { default as NewTabIcon } from './NewTab';
|
||||||
export { default as RoboSatsIcon } from "./RoboSats";
|
export { default as RoboSatsIcon } from './RoboSats';
|
||||||
export { default as RoboSatsNoTextIcon } from "./RoboSatsNoText";
|
export { default as RoboSatsNoTextIcon } from './RoboSatsNoText';
|
||||||
export { default as RoboSatsTextIcon } from "./RoboSatsText";
|
export { default as RoboSatsTextIcon } from './RoboSatsText';
|
||||||
export { default as SellSatsCheckedIcon } from "./SellSatsChecked";
|
export { default as SellSatsCheckedIcon } from './SellSatsChecked';
|
||||||
export { default as SellSatsIcon } from "./SellSats";
|
export { default as SellSatsIcon } from './SellSats';
|
||||||
export { default as SendReceiveIcon } from "./SendReceive";
|
export { default as SendReceiveIcon } from './SendReceive';
|
||||||
export { default as ExportIcon } from "./Export";
|
export { default as ExportIcon } from './Export';
|
||||||
export { default as UserNinjaIcon } from "./UserNinja";
|
export { default as UserNinjaIcon } from './UserNinja';
|
||||||
|
|
||||||
// Some Flags missing on react-flags
|
// Some Flags missing on react-flags
|
||||||
export { default as BasqueCountryFlag } from "./BasqueCountryFlag";
|
export { default as BasqueCountryFlag } from './BasqueCountryFlag';
|
||||||
export { default as CataloniaFlag } from "./CataloniaFlag";
|
export { default as CataloniaFlag } from './CataloniaFlag';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from 'react';
|
||||||
import { Box, LinearProgress } from "@mui/material"
|
import { Box, LinearProgress } from '@mui/material';
|
||||||
import { calcTimeDelta } from 'react-countdown';
|
import { calcTimeDelta } from 'react-countdown';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@ -7,10 +7,7 @@ type Props = {
|
|||||||
totalSecsExp: number;
|
totalSecsExp: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
const LinearDeterminate = ({
|
const LinearDeterminate = ({ expiresAt, totalSecsExp }: Props): JSX.Element => {
|
||||||
expiresAt,
|
|
||||||
totalSecsExp,
|
|
||||||
}: Props): JSX.Element => {
|
|
||||||
const [progress, setProgress] = useState<number>(0);
|
const [progress, setProgress] = useState<number>(0);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -28,7 +25,7 @@ const LinearDeterminate = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ width: '100%' }}>
|
<Box sx={{ width: '100%' }}>
|
||||||
<LinearProgress variant="determinate" value={progress} />
|
<LinearProgress variant='determinate' value={progress} />
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1 +1 @@
|
|||||||
export { default } from "./LinearDeterminate";
|
export { default } from './LinearDeterminate';
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,60 +1,107 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react';
|
||||||
import { withTranslation } from "react-i18next";
|
import { withTranslation } from 'react-i18next';
|
||||||
import PaymentIcon from './payment-methods/Icons'
|
import PaymentIcon from './payment-methods/Icons';
|
||||||
import {Tooltip} from "@mui/material"
|
import { Tooltip } from '@mui/material';
|
||||||
import { paymentMethods, swapDestinations } from "./payment-methods/Methods";
|
import { paymentMethods, swapDestinations } from './payment-methods/Methods';
|
||||||
|
|
||||||
const ns = [{name: "not specified",icon:'notspecified'}];
|
const ns = [{ name: 'not specified', icon: 'notspecified' }];
|
||||||
const methods = ns.concat(swapDestinations).concat(paymentMethods);
|
const methods = ns.concat(swapDestinations).concat(paymentMethods);
|
||||||
|
|
||||||
class PaymentText extends Component {
|
class PaymentText extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
parseText() {
|
||||||
|
const { t } = this.props;
|
||||||
|
var rows = [];
|
||||||
|
var custom_methods = this.props.text;
|
||||||
|
// Adds icons for each PaymentMethod that matches
|
||||||
|
methods.forEach((method, i) => {
|
||||||
|
if (this.props.text.includes(method.name)) {
|
||||||
|
custom_methods = custom_methods.replace(method.name, '');
|
||||||
|
rows.push(
|
||||||
|
<Tooltip
|
||||||
|
key={`${method.name}-${i}`}
|
||||||
|
placement='top'
|
||||||
|
enterTouchDelay={0}
|
||||||
|
title={t(method.name)}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'inline-block',
|
||||||
|
width: this.props.size + 2,
|
||||||
|
height: this.props.size,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<PaymentIcon width={this.props.size} height={this.props.size} icon={method.icon} />
|
||||||
|
</div>
|
||||||
|
</Tooltip>,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Adds a Custom icon if there are words that do not match
|
||||||
|
var chars_left = custom_methods
|
||||||
|
.replace(' ', '')
|
||||||
|
.replace(' ', '')
|
||||||
|
.replace(' ', '')
|
||||||
|
.replace(' ', '')
|
||||||
|
.replace(' ', '');
|
||||||
|
|
||||||
|
if (chars_left.length > 0) {
|
||||||
|
rows.push(
|
||||||
|
<Tooltip
|
||||||
|
key={'pushed'}
|
||||||
|
placement='top'
|
||||||
|
enterTouchDelay={0}
|
||||||
|
title={
|
||||||
|
this.props.verbose
|
||||||
|
? this.props.othersText
|
||||||
|
: this.props.othersText + ': ' + custom_methods
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: 'relative',
|
||||||
|
display: 'inline-block',
|
||||||
|
width: this.props.size + 2,
|
||||||
|
maxHeight: this.props.size,
|
||||||
|
top: '-1px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<PaymentIcon
|
||||||
|
width={this.props.size * 1.1}
|
||||||
|
height={this.props.size * 1.1}
|
||||||
|
icon={'custom'}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Tooltip>,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
parseText(){
|
if (this.props.verbose) {
|
||||||
const { t } = this.props;
|
|
||||||
var rows = [];
|
|
||||||
var custom_methods = this.props.text;
|
|
||||||
// Adds icons for each PaymentMethod that matches
|
|
||||||
methods.forEach((method, i) =>{
|
|
||||||
if(this.props.text.includes(method.name)){
|
|
||||||
custom_methods = custom_methods.replace(method.name,'')
|
|
||||||
rows.push(
|
|
||||||
<Tooltip key={`${method.name}-${i}`} placement="top" enterTouchDelay={0} title={t(method.name)}>
|
|
||||||
<div style={{display: 'inline-block', width: this.props.size+2, height: this.props.size}}>
|
|
||||||
<PaymentIcon width={this.props.size} height={this.props.size} icon={method.icon}/>
|
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Adds a Custom icon if there are words that do not match
|
|
||||||
var chars_left = custom_methods.replace(' ','').replace(' ','').replace(' ','').replace(' ','').replace(' ','')
|
|
||||||
|
|
||||||
if(chars_left.length > 0){rows.push(
|
|
||||||
<Tooltip key={"pushed"} placement="top" enterTouchDelay={0} title={this.props.verbose ? this.props.othersText: this.props.othersText+": "+ custom_methods} >
|
|
||||||
<div style={{position:'relative', display: 'inline-block',width: this.props.size+2, maxHeight: this.props.size, top:'-1px'}}>
|
|
||||||
<PaymentIcon width={this.props.size*1.1} height={this.props.size*1.1} icon={"custom"}/>
|
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
|
|
||||||
if(this.props.verbose){
|
|
||||||
return (<>{rows} <div style={{display: 'inline-block'}}> <span>{custom_methods}</span></div></>)
|
|
||||||
}else{
|
|
||||||
return rows
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
return (
|
||||||
<div style={{display:'flex',alignItems:'center', flexWrap:'wrap'}}>
|
<>
|
||||||
{this.parseText()}
|
{rows}{' '}
|
||||||
</div>
|
<div style={{ display: 'inline-block' }}>
|
||||||
)
|
{' '}
|
||||||
|
<span>{custom_methods}</span>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return rows;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap' }}>
|
||||||
|
{this.parseText()}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withTranslation()(PaymentText);
|
export default withTranslation()(PaymentText);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Slider } from "@mui/material"
|
import { Slider } from '@mui/material';
|
||||||
import { styled } from '@mui/material/styles';
|
import { styled } from '@mui/material/styles';
|
||||||
|
|
||||||
const RangeSlider = styled(Slider)(({ theme }) => ({
|
const RangeSlider = styled(Slider)(({ theme }) => ({
|
||||||
@ -6,15 +6,15 @@ const RangeSlider = styled(Slider)(({ theme }) => ({
|
|||||||
height: 3,
|
height: 3,
|
||||||
padding: '13px 0',
|
padding: '13px 0',
|
||||||
'& .MuiSlider-thumb': {
|
'& .MuiSlider-thumb': {
|
||||||
height: `${27/16}em`,
|
height: `${27 / 16}em`,
|
||||||
width: `${27/16}em`,
|
width: `${27 / 16}em`,
|
||||||
backgroundColor: '#fff',
|
backgroundColor: '#fff',
|
||||||
border: '1px solid currentColor',
|
border: '1px solid currentColor',
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
boxShadow: '0 0 0 8px rgba(58, 133, 137, 0.16)',
|
boxShadow: '0 0 0 8px rgba(58, 133, 137, 0.16)',
|
||||||
},
|
},
|
||||||
'& .range-bar': {
|
'& .range-bar': {
|
||||||
height: `${9/16}em`,
|
height: `${9 / 16}em`,
|
||||||
width: 1,
|
width: 1,
|
||||||
backgroundColor: 'currentColor',
|
backgroundColor: 'currentColor',
|
||||||
marginLeft: 1,
|
marginLeft: 1,
|
||||||
@ -22,13 +22,13 @@ const RangeSlider = styled(Slider)(({ theme }) => ({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
'& .MuiSlider-track': {
|
'& .MuiSlider-track': {
|
||||||
height: `${3/16}em`,
|
height: `${3 / 16}em`,
|
||||||
},
|
},
|
||||||
'& .MuiSlider-rail': {
|
'& .MuiSlider-rail': {
|
||||||
color: theme.palette.mode === 'dark' ? '#bfbfbf' : '#d8d8d8',
|
color: theme.palette.mode === 'dark' ? '#bfbfbf' : '#d8d8d8',
|
||||||
opacity: theme.palette.mode === 'dark' ? undefined : 1,
|
opacity: theme.palette.mode === 'dark' ? undefined : 1,
|
||||||
height: `${3/16}em`,
|
height: `${3 / 16}em`,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export default RangeSlider;
|
export default RangeSlider;
|
||||||
|
@ -1,61 +1,74 @@
|
|||||||
import React from "react"
|
import React from 'react';
|
||||||
import { Badge, Tooltip } from "@mui/material";
|
import { Badge, Tooltip } from '@mui/material';
|
||||||
import SmoothImage from 'react-smooth-image'
|
import SmoothImage from 'react-smooth-image';
|
||||||
|
|
||||||
import Order from "../../../models/Order.model"
|
import Order from '../../../models/Order.model';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
import { SendReceiveIcon } from "../../Icons";
|
import { SendReceiveIcon } from '../../Icons';
|
||||||
|
|
||||||
interface DepthChartProps {
|
interface DepthChartProps {
|
||||||
order: Order
|
order: Order;
|
||||||
}
|
}
|
||||||
|
|
||||||
const RobotAvatar: React.FC<DepthChartProps> = ({ order }) => {
|
const RobotAvatar: React.FC<DepthChartProps> = ({ order }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const avatarSrc: string = window.location.origin +'/static/assets/avatars/' + order?.maker_nick + '.png'
|
const avatarSrc: string =
|
||||||
|
window.location.origin + '/static/assets/avatars/' + order?.maker_nick + '.png';
|
||||||
|
|
||||||
const statusBadge = (
|
const statusBadge = (
|
||||||
<div style={{position:"relative", left:"6px", top:"1px"}}>
|
<div style={{ position: 'relative', left: '6px', top: '1px' }}>
|
||||||
{order?.type === 0 ?
|
{order?.type === 0 ? (
|
||||||
<SendReceiveIcon sx={{transform: "scaleX(-1)",height:"18px",width:"18px"}} color="secondary"/> :
|
<SendReceiveIcon
|
||||||
<SendReceiveIcon sx={{height:"20px",width:"20px"}} color="primary"/>}
|
sx={{ transform: 'scaleX(-1)', height: '18px', width: '18px' }}
|
||||||
|
color='secondary'
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<SendReceiveIcon sx={{ height: '20px', width: '20px' }} color='primary' />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
|
|
||||||
const statusBadgeColor = () => {
|
const statusBadgeColor = () => {
|
||||||
if(!order){ return }
|
if (!order) {
|
||||||
if(order.maker_status ==='Active'){ return("success") }
|
return;
|
||||||
if(order.maker_status ==='Seen recently'){ return("warning") }
|
}
|
||||||
if(order.maker_status ==='Inactive'){ return('error') }
|
if (order.maker_status === 'Active') {
|
||||||
}
|
return 'success';
|
||||||
|
}
|
||||||
|
if (order.maker_status === 'Seen recently') {
|
||||||
|
return 'warning';
|
||||||
|
}
|
||||||
|
if (order.maker_status === 'Inactive') {
|
||||||
|
return 'error';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return order ? (
|
return order ? (
|
||||||
<Tooltip placement="right" enterTouchDelay={0} title={t(order.maker_status) || ""}>
|
<Tooltip placement='right' enterTouchDelay={0} title={t(order.maker_status) || ''}>
|
||||||
<Badge
|
<Badge variant='dot' overlap='circular' badgeContent='' color={statusBadgeColor()}>
|
||||||
variant="dot"
|
<Badge
|
||||||
overlap="circular"
|
overlap='circular'
|
||||||
badgeContent=""
|
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
|
||||||
color={statusBadgeColor()}
|
|
||||||
>
|
|
||||||
<Badge
|
|
||||||
overlap="circular"
|
|
||||||
anchorOrigin={{horizontal: 'right', vertical: 'bottom'}}
|
|
||||||
badgeContent={statusBadge}
|
badgeContent={statusBadge}
|
||||||
>
|
>
|
||||||
<div style={{ width: 45, height: 45 }}>
|
<div style={{ width: 45, height: 45 }}>
|
||||||
<SmoothImage
|
<SmoothImage
|
||||||
src={avatarSrc}
|
src={avatarSrc}
|
||||||
imageStyles={{borderRadius: "50%",
|
imageStyles={{
|
||||||
transform: "scaleX(-1)",
|
borderRadius: '50%',
|
||||||
border: "0.3px solid #555",
|
transform: 'scaleX(-1)',
|
||||||
filter: "dropShadow(0.5px 0.5px 0.5px #000000)"}}
|
border: '0.3px solid #555',
|
||||||
|
filter: 'dropShadow(0.5px 0.5px 0.5px #000000)',
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Badge>
|
</Badge>
|
||||||
</Badge>
|
</Badge>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
) : <></>
|
) : (
|
||||||
}
|
<></>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default RobotAvatar
|
export default RobotAvatar;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,28 +1,28 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from 'react';
|
||||||
import { format } from "date-fns";
|
import { format } from 'date-fns';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
import {
|
import {
|
||||||
Avatar,
|
Avatar,
|
||||||
Badge,
|
Badge,
|
||||||
ToggleButton,
|
ToggleButton,
|
||||||
ToggleButtonGroup,
|
ToggleButtonGroup,
|
||||||
List,
|
List,
|
||||||
ListItem,
|
ListItem,
|
||||||
ListItemText,
|
ListItemText,
|
||||||
ListItemIcon,
|
ListItemIcon,
|
||||||
Grid,
|
Grid,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
IconButton,
|
IconButton,
|
||||||
Accordion,
|
Accordion,
|
||||||
AccordionSummary,
|
AccordionSummary,
|
||||||
AccordionDetails,
|
AccordionDetails,
|
||||||
Typography,
|
Typography,
|
||||||
} from "@mui/material"
|
} from '@mui/material';
|
||||||
import { pn } from "../utils/prettyNumbers";
|
import { pn } from '../utils/prettyNumbers';
|
||||||
import { saveAsJson } from "../utils/saveFile";
|
import { saveAsJson } from '../utils/saveFile';
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
import FlagWithProps from "./FlagWithProps";
|
import FlagWithProps from './FlagWithProps';
|
||||||
import ScheduleIcon from '@mui/icons-material/Schedule';
|
import ScheduleIcon from '@mui/icons-material/Schedule';
|
||||||
import PriceChangeIcon from '@mui/icons-material/PriceChange';
|
import PriceChangeIcon from '@mui/icons-material/PriceChange';
|
||||||
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
||||||
@ -32,7 +32,7 @@ import RouteIcon from '@mui/icons-material/Route';
|
|||||||
import AccountBoxIcon from '@mui/icons-material/AccountBox';
|
import AccountBoxIcon from '@mui/icons-material/AccountBox';
|
||||||
import LockOpenIcon from '@mui/icons-material/LockOpen';
|
import LockOpenIcon from '@mui/icons-material/LockOpen';
|
||||||
import LinkIcon from '@mui/icons-material/Link';
|
import LinkIcon from '@mui/icons-material/Link';
|
||||||
import { RoboSatsNoTextIcon , SendReceiveIcon , BitcoinIcon} from "./Icons";
|
import { RoboSatsNoTextIcon, SendReceiveIcon, BitcoinIcon } from './Icons';
|
||||||
|
|
||||||
interface Item {
|
interface Item {
|
||||||
id: string;
|
id: string;
|
||||||
@ -48,7 +48,7 @@ type Props = {
|
|||||||
takerSummary: Record<string, Item>;
|
takerSummary: Record<string, Item>;
|
||||||
platformSummary: Record<string, Item>;
|
platformSummary: Record<string, Item>;
|
||||||
orderId: number;
|
orderId: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
const TradeSummary = ({
|
const TradeSummary = ({
|
||||||
isMaker,
|
isMaker,
|
||||||
@ -60,186 +60,261 @@ const TradeSummary = ({
|
|||||||
platformSummary,
|
platformSummary,
|
||||||
orderId,
|
orderId,
|
||||||
}: Props): JSX.Element => {
|
}: Props): JSX.Element => {
|
||||||
const { t , i18n } = useTranslation();
|
const { t, i18n } = useTranslation();
|
||||||
const [buttonValue, setButtonValue] = useState<number>(isMaker ? 0 : 2);
|
const [buttonValue, setButtonValue] = useState<number>(isMaker ? 0 : 2);
|
||||||
var userSummary = buttonValue == 0 ? makerSummary : takerSummary;
|
var userSummary = buttonValue == 0 ? makerSummary : takerSummary;
|
||||||
const contractTimestamp = new Date(platformSummary.contract_timestamp)
|
const contractTimestamp = new Date(platformSummary.contract_timestamp);
|
||||||
const total_time = platformSummary.contract_total_time
|
const total_time = platformSummary.contract_total_time;
|
||||||
const hours = parseInt(total_time / 3600)
|
const hours = parseInt(total_time / 3600);
|
||||||
const mins = parseInt((total_time - hours * 3600) / 60)
|
const mins = parseInt((total_time - hours * 3600) / 60);
|
||||||
const secs = parseInt(total_time - hours * 3600 - mins * 60)
|
const secs = parseInt(total_time - hours * 3600 - mins * 60);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid item xs={12} align="center">
|
<Grid item xs={12} align='center'>
|
||||||
<Accordion defaultExpanded={true} elevation={0} sx={{width:322, position:'relative', right:8}}>
|
<Accordion
|
||||||
<AccordionSummary expandIcon={<ExpandMoreIcon sx={{width:28}} color="primary"/>}>
|
defaultExpanded={true}
|
||||||
<Typography sx={{flexGrow:1}} color="text.secondary">{t("Trade Summary")}</Typography>
|
elevation={0}
|
||||||
|
sx={{ width: 322, position: 'relative', right: 8 }}
|
||||||
|
>
|
||||||
|
<AccordionSummary expandIcon={<ExpandMoreIcon sx={{ width: 28 }} color='primary' />}>
|
||||||
|
<Typography sx={{ flexGrow: 1 }} color='text.secondary'>
|
||||||
|
{t('Trade Summary')}
|
||||||
|
</Typography>
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
<AccordionDetails>
|
<AccordionDetails>
|
||||||
<div style={{position:'relative',left:14, display:'flex',alignItems:'center', justifyContent:'center', flexWrap:'wrap'}}>
|
<div
|
||||||
<ToggleButtonGroup
|
style={{
|
||||||
size="small"
|
position: 'relative',
|
||||||
value={buttonValue}
|
left: 14,
|
||||||
exclusive>
|
display: 'flex',
|
||||||
<ToggleButton value={0} disableRipple={true} onClick={() => setButtonValue(0)}>
|
alignItems: 'center',
|
||||||
<Avatar
|
justifyContent: 'center',
|
||||||
className="flippedSmallAvatar"
|
flexWrap: 'wrap',
|
||||||
sx={{height:24,width:24}}
|
}}
|
||||||
alt={makerNick}
|
>
|
||||||
src={window.location.origin +'/static/assets/avatars/' + makerNick + '.png'}
|
<ToggleButtonGroup size='small' value={buttonValue} exclusive>
|
||||||
/>
|
<ToggleButton value={0} disableRipple={true} onClick={() => setButtonValue(0)}>
|
||||||
|
<Avatar
|
||||||
{t("Maker")}
|
className='flippedSmallAvatar'
|
||||||
</ToggleButton>
|
sx={{ height: 24, width: 24 }}
|
||||||
<ToggleButton value={1} disableRipple={true} onClick={() => setButtonValue(1)}>
|
alt={makerNick}
|
||||||
<RoboSatsNoTextIcon/>
|
src={window.location.origin + '/static/assets/avatars/' + makerNick + '.png'}
|
||||||
</ToggleButton>
|
/>
|
||||||
<ToggleButton value={2} disableRipple={true} onClick={() => setButtonValue(2)}>
|
|
||||||
{t("Taker")}
|
{t('Maker')}
|
||||||
|
</ToggleButton>
|
||||||
<Avatar
|
<ToggleButton value={1} disableRipple={true} onClick={() => setButtonValue(1)}>
|
||||||
className="smallAvatar"
|
<RoboSatsNoTextIcon />
|
||||||
sx={{height:28,width:28}}
|
</ToggleButton>
|
||||||
alt={takerNick}
|
<ToggleButton value={2} disableRipple={true} onClick={() => setButtonValue(2)}>
|
||||||
src={window.location.origin +'/static/assets/avatars/' + takerNick + '.png'}
|
{t('Taker')}
|
||||||
/>
|
|
||||||
</ToggleButton>
|
<Avatar
|
||||||
|
className='smallAvatar'
|
||||||
|
sx={{ height: 28, width: 28 }}
|
||||||
|
alt={takerNick}
|
||||||
|
src={window.location.origin + '/static/assets/avatars/' + takerNick + '.png'}
|
||||||
|
/>
|
||||||
|
</ToggleButton>
|
||||||
</ToggleButtonGroup>
|
</ToggleButtonGroup>
|
||||||
<Tooltip enterTouchDelay={250} title={t("Save trade summary as file")}>
|
<Tooltip enterTouchDelay={250} title={t('Save trade summary as file')}>
|
||||||
<span>
|
<span>
|
||||||
<IconButton
|
<IconButton
|
||||||
color="primary"
|
color='primary'
|
||||||
onClick={()=> saveAsJson(`order${orderId}-summary.json`, {'order_id':orderId,'currency':currencyCode,'maker':makerSummary,'taker':takerSummary,'platform':platformSummary})}
|
onClick={() =>
|
||||||
>
|
saveAsJson(`order${orderId}-summary.json`, {
|
||||||
<DownloadIcon sx={{width:26, height:26}}/>
|
order_id: orderId,
|
||||||
</IconButton>
|
currency: currencyCode,
|
||||||
</span>
|
maker: makerSummary,
|
||||||
</Tooltip>
|
taker: takerSummary,
|
||||||
</div>
|
platform: platformSummary,
|
||||||
{/* Maker/Taker Summary */}
|
})
|
||||||
<div style={{display: [0,2].includes(buttonValue) ? '':'none'}}>
|
}
|
||||||
<List dense={true}>
|
>
|
||||||
<ListItem>
|
<DownloadIcon sx={{ width: 26, height: 26 }} />
|
||||||
<ListItemIcon>
|
</IconButton>
|
||||||
<Badge
|
</span>
|
||||||
overlap="circular"
|
</Tooltip>
|
||||||
anchorOrigin={{horizontal: 'right', vertical: 'bottom'}}
|
</div>
|
||||||
badgeContent={<div
|
{/* Maker/Taker Summary */}
|
||||||
style={{position:"relative", left:"3px", top:"2px"}}>
|
<div style={{ display: [0, 2].includes(buttonValue) ? '' : 'none' }}>
|
||||||
{userSummary.is_buyer ?
|
<List dense={true}>
|
||||||
<SendReceiveIcon
|
<ListItem>
|
||||||
sx={{transform: "scaleX(-1)",height:"18px",width:"18px"}}
|
<ListItemIcon>
|
||||||
color="secondary"/>
|
<Badge
|
||||||
: <SendReceiveIcon
|
overlap='circular'
|
||||||
sx={{height:"18px",width:"18px"}}
|
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
|
||||||
color="primary"/>
|
badgeContent={
|
||||||
}
|
<div style={{ position: 'relative', left: '3px', top: '2px' }}>
|
||||||
</div>}>
|
{userSummary.is_buyer ? (
|
||||||
<AccountBoxIcon sx={{position:'relative',left:-2,width:28,height:28}}/>
|
<SendReceiveIcon
|
||||||
</Badge>
|
sx={{ transform: 'scaleX(-1)', height: '18px', width: '18px' }}
|
||||||
</ListItemIcon>
|
color='secondary'
|
||||||
<ListItemText
|
/>
|
||||||
primary={userSummary.is_buyer ? t("Buyer") : t("Seller")}
|
) : (
|
||||||
secondary={t("User role")}/>
|
<SendReceiveIcon sx={{ height: '18px', width: '18px' }} color='primary' />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<AccountBoxIcon
|
||||||
|
sx={{ position: 'relative', left: -2, width: 28, height: 28 }}
|
||||||
|
/>
|
||||||
|
</Badge>
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText
|
||||||
|
primary={userSummary.is_buyer ? t('Buyer') : t('Seller')}
|
||||||
|
secondary={t('User role')}
|
||||||
|
/>
|
||||||
|
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<div style={{position:'relative',left:15,zoom:1.25,opacity: 0.7,msZoom:1.25,WebkitZoom:1.25,MozTransform:'scale(1.25,1.25)',MozTransformOrigin:'left center'}}>
|
<div
|
||||||
<FlagWithProps code={currencyCode}/>
|
style={{
|
||||||
</div>
|
position: 'relative',
|
||||||
</ListItemIcon>
|
left: 15,
|
||||||
<ListItemText
|
zoom: 1.25,
|
||||||
primary={(userSummary.is_buyer ? pn(userSummary.sent_fiat) : pn(userSummary.received_fiat))+" "+currencyCode}
|
opacity: 0.7,
|
||||||
secondary={userSummary.is_buyer ? t("Sent") : t("Received")}/>
|
msZoom: 1.25,
|
||||||
</ListItem>
|
WebkitZoom: 1.25,
|
||||||
|
MozTransform: 'scale(1.25,1.25)',
|
||||||
<ListItem>
|
MozTransformOrigin: 'left center',
|
||||||
<ListItemIcon>
|
}}
|
||||||
<BitcoinIcon/>
|
>
|
||||||
</ListItemIcon>
|
<FlagWithProps code={currencyCode} />
|
||||||
<ListItemText
|
</div>
|
||||||
primary={pn(userSummary.is_buyer ? userSummary.received_sats : userSummary.sent_sats)+" Sats"}
|
</ListItemIcon>
|
||||||
secondary={userSummary.is_buyer ? "BTC received" : "BTC sent"}/>
|
<ListItemText
|
||||||
|
primary={
|
||||||
|
(userSummary.is_buyer
|
||||||
|
? pn(userSummary.sent_fiat)
|
||||||
|
: pn(userSummary.received_fiat)) +
|
||||||
|
' ' +
|
||||||
|
currencyCode
|
||||||
|
}
|
||||||
|
secondary={userSummary.is_buyer ? t('Sent') : t('Received')}
|
||||||
|
/>
|
||||||
|
</ListItem>
|
||||||
|
|
||||||
<ListItemText
|
<ListItem>
|
||||||
primary={t("{{tradeFeeSats}} Sats ({{tradeFeePercent}}%)",{tradeFeeSats:pn(userSummary.trade_fee_sats),tradeFeePercent:parseFloat((userSummary.trade_fee_percent*100).toPrecision(3))})}
|
<ListItemIcon>
|
||||||
secondary={"Trade fee"}/>
|
<BitcoinIcon />
|
||||||
</ListItem>
|
</ListItemIcon>
|
||||||
|
<ListItemText
|
||||||
{userSummary.is_swap ?
|
primary={
|
||||||
<ListItem>
|
pn(userSummary.is_buyer ? userSummary.received_sats : userSummary.sent_sats) +
|
||||||
<ListItemIcon>
|
' Sats'
|
||||||
<LinkIcon/>
|
}
|
||||||
</ListItemIcon>
|
secondary={userSummary.is_buyer ? 'BTC received' : 'BTC sent'}
|
||||||
<ListItemText
|
/>
|
||||||
primary={t("{{swapFeeSats}} Sats ({{swapFeePercent}}%)" , {swapFeeSats:pn(userSummary.swap_fee_sats), swapFeePercent:userSummary.swap_fee_percent})}
|
|
||||||
secondary={t("Onchain swap fee")}/>
|
|
||||||
<ListItemText
|
|
||||||
primary={t("{{miningFeeSats}} Sats",{miningFeeSats:pn(userSummary.mining_fee_sats)})}
|
|
||||||
secondary={t("Mining fee")}/>
|
|
||||||
</ListItem>
|
|
||||||
: null}
|
|
||||||
|
|
||||||
<ListItem>
|
<ListItemText
|
||||||
<ListItemIcon>
|
primary={t('{{tradeFeeSats}} Sats ({{tradeFeePercent}}%)', {
|
||||||
<LockOpenIcon color="success"/>
|
tradeFeeSats: pn(userSummary.trade_fee_sats),
|
||||||
</ListItemIcon>
|
tradeFeePercent: parseFloat(
|
||||||
<ListItemText
|
(userSummary.trade_fee_percent * 100).toPrecision(3),
|
||||||
primary={t("{{bondSats}} Sats ({{bondPercent}}%)" , {bondSats:pn(userSummary.bond_size_sats), bondPercent:userSummary.bond_size_percent})}
|
),
|
||||||
secondary={buttonValue === 0 ? t("Maker bond") : t("Taker bond") }/>
|
})}
|
||||||
<ListItemText
|
secondary={'Trade fee'}
|
||||||
sx={{color:'#2e7d32'}}
|
/>
|
||||||
primary={<b>{t("Unlocked")}</b>}/>
|
</ListItem>
|
||||||
</ListItem>
|
|
||||||
</List>
|
{userSummary.is_swap ? (
|
||||||
</div>
|
|
||||||
{/* Platform Summary */}
|
|
||||||
<div style={{display: buttonValue == 1 ? '':'none'}}>
|
|
||||||
<List dense={true}>
|
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<AccountBalanceIcon/>
|
<LinkIcon />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={t("{{revenueSats}} Sats",{revenueSats:pn(platformSummary.trade_revenue_sats)})}
|
primary={t('{{swapFeeSats}} Sats ({{swapFeePercent}}%)', {
|
||||||
secondary={t("Platform trade revenue")}/>
|
swapFeeSats: pn(userSummary.swap_fee_sats),
|
||||||
</ListItem>
|
swapFeePercent: userSummary.swap_fee_percent,
|
||||||
|
})}
|
||||||
<ListItem>
|
secondary={t('Onchain swap fee')}
|
||||||
<ListItemIcon>
|
/>
|
||||||
<RouteIcon/>
|
<ListItemText
|
||||||
</ListItemIcon>
|
primary={t('{{miningFeeSats}} Sats', {
|
||||||
<ListItemText
|
miningFeeSats: pn(userSummary.mining_fee_sats),
|
||||||
primary={t("{{routingFeeSats}} MiliSats",{routingFeeSats:pn(platformSummary.routing_fee_sats)})}
|
})}
|
||||||
secondary={t("Platform covered routing fee")}/>
|
secondary={t('Mining fee')}
|
||||||
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
) : null}
|
||||||
|
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<PriceChangeIcon/>
|
<LockOpenIcon color='success' />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={`${pn(platformSummary.contract_exchange_rate.toPrecision(7))} ${currencyCode}/BTC`}
|
primary={t('{{bondSats}} Sats ({{bondPercent}}%)', {
|
||||||
secondary={t("Contract exchange rate")}/>
|
bondSats: pn(userSummary.bond_size_sats),
|
||||||
</ListItem>
|
bondPercent: userSummary.bond_size_percent,
|
||||||
|
})}
|
||||||
<ListItem>
|
secondary={buttonValue === 0 ? t('Maker bond') : t('Taker bond')}
|
||||||
<ListItemText
|
/>
|
||||||
primary={format(contractTimestamp, "do LLL HH:mm:ss")}
|
<ListItemText sx={{ color: '#2e7d32' }} primary={<b>{t('Unlocked')}</b>} />
|
||||||
secondary={t("Timestamp")}/>
|
</ListItem>
|
||||||
<ListItemIcon>
|
</List>
|
||||||
<ScheduleIcon/>
|
</div>
|
||||||
</ListItemIcon>
|
{/* Platform Summary */}
|
||||||
<ListItemText
|
<div style={{ display: buttonValue == 1 ? '' : 'none' }}>
|
||||||
primary={`${String(hours).padStart(2, '0')}:${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`}
|
<List dense={true}>
|
||||||
secondary={t("Completed in")}/>
|
<ListItem>
|
||||||
</ListItem>
|
<ListItemIcon>
|
||||||
</List>
|
<AccountBalanceIcon />
|
||||||
</div>
|
</ListItemIcon>
|
||||||
|
<ListItemText
|
||||||
|
primary={t('{{revenueSats}} Sats', {
|
||||||
|
revenueSats: pn(platformSummary.trade_revenue_sats),
|
||||||
|
})}
|
||||||
|
secondary={t('Platform trade revenue')}
|
||||||
|
/>
|
||||||
|
</ListItem>
|
||||||
|
|
||||||
|
<ListItem>
|
||||||
|
<ListItemIcon>
|
||||||
|
<RouteIcon />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText
|
||||||
|
primary={t('{{routingFeeSats}} MiliSats', {
|
||||||
|
routingFeeSats: pn(platformSummary.routing_fee_sats),
|
||||||
|
})}
|
||||||
|
secondary={t('Platform covered routing fee')}
|
||||||
|
/>
|
||||||
|
</ListItem>
|
||||||
|
|
||||||
|
<ListItem>
|
||||||
|
<ListItemIcon>
|
||||||
|
<PriceChangeIcon />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText
|
||||||
|
primary={`${pn(
|
||||||
|
platformSummary.contract_exchange_rate.toPrecision(7),
|
||||||
|
)} ${currencyCode}/BTC`}
|
||||||
|
secondary={t('Contract exchange rate')}
|
||||||
|
/>
|
||||||
|
</ListItem>
|
||||||
|
|
||||||
|
<ListItem>
|
||||||
|
<ListItemText
|
||||||
|
primary={format(contractTimestamp, 'do LLL HH:mm:ss')}
|
||||||
|
secondary={t('Timestamp')}
|
||||||
|
/>
|
||||||
|
<ListItemIcon>
|
||||||
|
<ScheduleIcon />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText
|
||||||
|
primary={`${String(hours).padStart(2, '0')}:${String(mins).padStart(
|
||||||
|
2,
|
||||||
|
'0',
|
||||||
|
)}:${String(secs).padStart(2, '0')}`}
|
||||||
|
secondary={t('Completed in')}
|
||||||
|
/>
|
||||||
|
</ListItem>
|
||||||
|
</List>
|
||||||
|
</div>
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
</Grid>
|
</Grid>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default TradeSummary;
|
export default TradeSummary;
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react';
|
||||||
import { withTranslation, Trans} from "react-i18next";
|
import { withTranslation, Trans } from 'react-i18next';
|
||||||
import {Paper, Alert, AlertTitle, Button, Link} from "@mui/material"
|
import { Paper, Alert, AlertTitle, Button, Link } from '@mui/material';
|
||||||
import MediaQuery from 'react-responsive'
|
import MediaQuery from 'react-responsive';
|
||||||
|
|
||||||
class UnsafeAlert extends Component {
|
class UnsafeAlert extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -11,86 +11,126 @@ class UnsafeAlert extends Component {
|
|||||||
isSelfhosted: this.isSelfhosted(),
|
isSelfhosted: this.isSelfhosted(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
getHost(){
|
getHost() {
|
||||||
var url = (window.location != window.parent.location) ? this.getHost(document.referrer) : document.location.href;
|
var url =
|
||||||
return url.split('/')[2]
|
window.location != window.parent.location
|
||||||
|
? this.getHost(document.referrer)
|
||||||
|
: document.location.href;
|
||||||
|
return url.split('/')[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
isSelfhosted(){
|
isSelfhosted() {
|
||||||
var http = new XMLHttpRequest();
|
var http = new XMLHttpRequest();
|
||||||
http.open('HEAD', `${location.protocol}//${this.getHost()}/selfhosted`, false);
|
http.open('HEAD', `${location.protocol}//${this.getHost()}/selfhosted`, false);
|
||||||
http.send();
|
http.send();
|
||||||
return http.status!=404;
|
return http.status != 404;
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_urls = [
|
safe_urls = [
|
||||||
'robosats6tkf3eva7x2voqso3a5wcorsnw34jveyxfqi2fu7oyheasid.onion',
|
'robosats6tkf3eva7x2voqso3a5wcorsnw34jveyxfqi2fu7oyheasid.onion',
|
||||||
'robotestagw3dcxmd66r4rgksb4nmmr43fh77bzn2ia2eucduyeafnyd.onion',
|
'robotestagw3dcxmd66r4rgksb4nmmr43fh77bzn2ia2eucduyeafnyd.onion',
|
||||||
'robodevs7ixniseezbv7uryxhamtz3hvcelzfwpx3rvoipttjomrmpqd.onion',
|
'robodevs7ixniseezbv7uryxhamtz3hvcelzfwpx3rvoipttjomrmpqd.onion',
|
||||||
'robosats.i2p',
|
'robosats.i2p',
|
||||||
'r7r4sckft6ptmk4r2jajiuqbowqyxiwsle4iyg4fijtoordc6z7a.b32.i2p',
|
'r7r4sckft6ptmk4r2jajiuqbowqyxiwsle4iyg4fijtoordc6z7a.b32.i2p',
|
||||||
]
|
];
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { t, i18n} = this.props;
|
const { t, i18n } = this.props;
|
||||||
|
|
||||||
// If alert is hidden return null
|
// If alert is hidden return null
|
||||||
if (!this.state.show){return null}
|
if (!this.state.show) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Show selfhosted notice
|
// Show selfhosted notice
|
||||||
if (this.state.isSelfhosted){
|
if (this.state.isSelfhosted) {
|
||||||
return(
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Paper elevation={6} className="alertUnsafe">
|
<Paper elevation={6} className='alertUnsafe'>
|
||||||
<Alert severity="success" sx={{maxHeight:"120px"}}
|
<Alert
|
||||||
action={<Button color="success" onClick={() => this.setState({show:false})}>{t("Hide")}</Button>}
|
severity='success'
|
||||||
>
|
sx={{ maxHeight: '120px' }}
|
||||||
<AlertTitle>{t("You are self-hosting RoboSats")}</AlertTitle>
|
action={
|
||||||
{t("RoboSats client is served from your own node granting you the strongest security and privacy.")}
|
<Button color='success' onClick={() => this.setState({ show: false })}>
|
||||||
|
{t('Hide')}
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<AlertTitle>{t('You are self-hosting RoboSats')}</AlertTitle>
|
||||||
|
{t(
|
||||||
|
'RoboSats client is served from your own node granting you the strongest security and privacy.',
|
||||||
|
)}
|
||||||
</Alert>
|
</Alert>
|
||||||
</Paper>
|
</Paper>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show unsafe alert
|
// Show unsafe alert
|
||||||
if (!this.safe_urls.includes(this.getHost())){
|
if (!this.safe_urls.includes(this.getHost())) {
|
||||||
return(
|
return (
|
||||||
<div>
|
<div>
|
||||||
<MediaQuery minWidth={800}>
|
<MediaQuery minWidth={800}>
|
||||||
<Paper elevation={6} className="alertUnsafe">
|
<Paper elevation={6} className='alertUnsafe'>
|
||||||
<Alert severity="warning" sx={{maxHeight:"100px"}}
|
<Alert
|
||||||
action={<Button onClick={() => this.setState({show:false})}>{t("Hide")}</Button>}
|
severity='warning'
|
||||||
|
sx={{ maxHeight: '100px' }}
|
||||||
|
action={<Button onClick={() => this.setState({ show: false })}>{t('Hide')}</Button>}
|
||||||
>
|
>
|
||||||
<AlertTitle>{t("You are not using RoboSats privately")}</AlertTitle>
|
<AlertTitle>{t('You are not using RoboSats privately')}</AlertTitle>
|
||||||
<Trans i18nKey="desktop_unsafe_alert">
|
<Trans i18nKey='desktop_unsafe_alert'>
|
||||||
Some features are disabled for your protection (e.g. chat) and you will not be able to complete a
|
Some features are disabled for your protection (e.g. chat) and you will not be
|
||||||
trade without them. To protect your privacy and fully enable RoboSats, use <Link href='https://www.torproject.org/download/' target="_blank">Tor Browser</Link> and visit the <Link href='http://robosats6tkf3eva7x2voqso3a5wcorsnw34jveyxfqi2fu7oyheasid.onion' target="_blank">Onion</Link> site.
|
able to complete a trade without them. To protect your privacy and fully enable
|
||||||
|
RoboSats, use{' '}
|
||||||
|
<Link href='https://www.torproject.org/download/' target='_blank'>
|
||||||
|
Tor Browser
|
||||||
|
</Link>{' '}
|
||||||
|
and visit the{' '}
|
||||||
|
<Link
|
||||||
|
href='http://robosats6tkf3eva7x2voqso3a5wcorsnw34jveyxfqi2fu7oyheasid.onion'
|
||||||
|
target='_blank'
|
||||||
|
>
|
||||||
|
Onion
|
||||||
|
</Link>{' '}
|
||||||
|
site.
|
||||||
</Trans>
|
</Trans>
|
||||||
</Alert>
|
</Alert>
|
||||||
</Paper>
|
</Paper>
|
||||||
</MediaQuery>
|
</MediaQuery>
|
||||||
|
|
||||||
<MediaQuery maxWidth={799}>
|
<MediaQuery maxWidth={799}>
|
||||||
<Paper elevation={6} className="alertUnsafe">
|
<Paper elevation={6} className='alertUnsafe'>
|
||||||
<Alert severity="warning" sx={{maxHeight:"120px"}}>
|
<Alert severity='warning' sx={{ maxHeight: '120px' }}>
|
||||||
<AlertTitle>{t("You are not using RoboSats privately")}</AlertTitle>
|
<AlertTitle>{t('You are not using RoboSats privately')}</AlertTitle>
|
||||||
<Trans i18nKey="phone_unsafe_alert">
|
<Trans i18nKey='phone_unsafe_alert'>
|
||||||
You will not be able to complete a
|
You will not be able to complete a trade. Use{' '}
|
||||||
trade. Use <Link href='https://www.torproject.org/download/' target="_blank">Tor Browser</Link> and visit the <Link href='http://robosats6tkf3eva7x2voqso3a5wcorsnw34jveyxfqi2fu7oyheasid.onion' target="_blank">Onion</Link> site.
|
<Link href='https://www.torproject.org/download/' target='_blank'>
|
||||||
</Trans>
|
Tor Browser
|
||||||
<div style={{width: '100%'}}>
|
</Link>{' '}
|
||||||
</div>
|
and visit the{' '}
|
||||||
<div align="center">
|
<Link
|
||||||
<Button className="hideAlertButton" onClick={() => this.setState({show:false})}>{t("Hide")}</Button>
|
href='http://robosats6tkf3eva7x2voqso3a5wcorsnw34jveyxfqi2fu7oyheasid.onion'
|
||||||
</div>
|
target='_blank'
|
||||||
</Alert>
|
>
|
||||||
|
Onion
|
||||||
|
</Link>{' '}
|
||||||
|
site.
|
||||||
|
</Trans>
|
||||||
|
<div style={{ width: '100%' }}></div>
|
||||||
|
<div align='center'>
|
||||||
|
<Button
|
||||||
|
className='hideAlertButton'
|
||||||
|
onClick={() => this.setState({ show: false })}
|
||||||
|
>
|
||||||
|
{t('Hide')}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Alert>
|
||||||
</Paper>
|
</Paper>
|
||||||
</MediaQuery>
|
</MediaQuery>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,32 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import { withTranslation } from "react-i18next";
|
import { withTranslation } from 'react-i18next';
|
||||||
import { Button , Tooltip, Grid, Typography, TextField, ButtonGroup, CircularProgress, IconButton} from "@mui/material"
|
import {
|
||||||
import { Link } from 'react-router-dom'
|
Button,
|
||||||
import SmoothImage from 'react-smooth-image'
|
Tooltip,
|
||||||
import { InfoDialog } from './Dialogs'
|
Grid,
|
||||||
|
Typography,
|
||||||
|
TextField,
|
||||||
|
ButtonGroup,
|
||||||
|
CircularProgress,
|
||||||
|
IconButton,
|
||||||
|
} from '@mui/material';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import SmoothImage from 'react-smooth-image';
|
||||||
|
import { InfoDialog } from './Dialogs';
|
||||||
|
|
||||||
import SmartToyIcon from '@mui/icons-material/SmartToy';
|
import SmartToyIcon from '@mui/icons-material/SmartToy';
|
||||||
import CasinoIcon from '@mui/icons-material/Casino';
|
import CasinoIcon from '@mui/icons-material/Casino';
|
||||||
import ContentCopy from "@mui/icons-material/ContentCopy";
|
import ContentCopy from '@mui/icons-material/ContentCopy';
|
||||||
import BoltIcon from '@mui/icons-material/Bolt';
|
import BoltIcon from '@mui/icons-material/Bolt';
|
||||||
import DownloadIcon from '@mui/icons-material/Download';
|
import DownloadIcon from '@mui/icons-material/Download';
|
||||||
import { RoboSatsNoTextIcon } from "./Icons";
|
import { RoboSatsNoTextIcon } from './Icons';
|
||||||
|
|
||||||
import { sha256 } from 'js-sha256';
|
import { sha256 } from 'js-sha256';
|
||||||
import { genBase62Token, tokenStrength } from "../utils/token";
|
import { genBase62Token, tokenStrength } from '../utils/token';
|
||||||
import { genKey } from "../utils/pgp";
|
import { genKey } from '../utils/pgp';
|
||||||
import { getCookie, writeCookie, deleteCookie } from "../utils/cookies";
|
import { getCookie, writeCookie, deleteCookie } from '../utils/cookies';
|
||||||
import { saveAsJson } from "../utils/saveFile";
|
import { saveAsJson } from '../utils/saveFile';
|
||||||
import { copyToClipboard } from "../utils/clipboard";
|
import { copyToClipboard } from '../utils/clipboard';
|
||||||
|
|
||||||
class UserGenPage extends Component {
|
class UserGenPage extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -25,7 +34,7 @@ class UserGenPage extends Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
openInfo: false,
|
openInfo: false,
|
||||||
tokenHasChanged: false,
|
tokenHasChanged: false,
|
||||||
token: ""
|
token: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
this.refCode = this.props.match.params.refCode;
|
this.refCode = this.props.match.params.refCode;
|
||||||
@ -34,304 +43,398 @@ class UserGenPage extends Component {
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
// Checks in parent HomePage if there is already a nick and token
|
// Checks in parent HomePage if there is already a nick and token
|
||||||
// Displays the existing one
|
// Displays the existing one
|
||||||
if (this.props.nickname != null){
|
if (this.props.nickname != null) {
|
||||||
this.setState({
|
this.setState({
|
||||||
nickname: this.props.nickname,
|
nickname: this.props.nickname,
|
||||||
token: this.props.token? this.props.token : "",
|
token: this.props.token ? this.props.token : '',
|
||||||
avatarUrl: '/static/assets/avatars/' + this.props.nickname + '.png',
|
avatarUrl: '/static/assets/avatars/' + this.props.nickname + '.png',
|
||||||
loadingRobot: false
|
loadingRobot: false,
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else{
|
var newToken = genBase62Token(36);
|
||||||
var newToken = genBase62Token(36)
|
|
||||||
this.setState({
|
this.setState({
|
||||||
token: newToken
|
token: newToken,
|
||||||
});
|
});
|
||||||
this.getGeneratedUser(newToken);
|
this.getGeneratedUser(newToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getGeneratedUser=(token)=>{
|
getGeneratedUser = (token) => {
|
||||||
|
|
||||||
const strength = tokenStrength(token);
|
const strength = tokenStrength(token);
|
||||||
const refCode = this.refCode
|
const refCode = this.refCode;
|
||||||
|
|
||||||
const requestOptions = genKey(token).then(function(key) {
|
const requestOptions = genKey(token).then(function (key) {
|
||||||
return {
|
return {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {'Content-Type':'application/json', 'X-CSRFToken': getCookie('csrftoken')},
|
headers: { 'Content-Type': 'application/json', 'X-CSRFToken': getCookie('csrftoken') },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
token_sha256: sha256(token),
|
token_sha256: sha256(token),
|
||||||
public_key: key.publicKeyArmored,
|
public_key: key.publicKeyArmored,
|
||||||
encrypted_private_key: key.encryptedPrivateKeyArmored,
|
encrypted_private_key: key.encryptedPrivateKeyArmored,
|
||||||
unique_values: strength.uniqueValues,
|
unique_values: strength.uniqueValues,
|
||||||
counts: strength.counts,
|
counts: strength.counts,
|
||||||
length: token.length,
|
length: token.length,
|
||||||
ref_code: refCode,
|
ref_code: refCode,
|
||||||
})
|
}),
|
||||||
}}
|
};
|
||||||
);
|
});
|
||||||
|
|
||||||
|
console.log(requestOptions);
|
||||||
|
|
||||||
console.log(requestOptions)
|
|
||||||
|
|
||||||
requestOptions.then((options) =>
|
requestOptions.then((options) =>
|
||||||
fetch("/api/user/",options)
|
fetch('/api/user/', options)
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
.then((data) => { console.log(data) &
|
.then((data) => {
|
||||||
this.setState({
|
console.log(data) &
|
||||||
|
this.setState({
|
||||||
nickname: data.nickname,
|
nickname: data.nickname,
|
||||||
bit_entropy: data.token_bits_entropy,
|
bit_entropy: data.token_bits_entropy,
|
||||||
avatarUrl: '/static/assets/avatars/' + data.nickname + '.png',
|
avatarUrl: '/static/assets/avatars/' + data.nickname + '.png',
|
||||||
shannon_entropy: data.token_shannon_entropy,
|
shannon_entropy: data.token_shannon_entropy,
|
||||||
bad_request: data.bad_request,
|
bad_request: data.bad_request,
|
||||||
found: data.found,
|
found: data.found,
|
||||||
loadingRobot:false,
|
loadingRobot: false,
|
||||||
stealthInvoices: data.wants_stealth,
|
stealthInvoices: data.wants_stealth,
|
||||||
})
|
}) &
|
||||||
&
|
// Add nick and token to App state (token only if not a bad request)
|
||||||
// Add nick and token to App state (token only if not a bad request)
|
(data.bad_request
|
||||||
(data.bad_request ? this.props.setAppState({
|
? this.props.setAppState({
|
||||||
nickname: data.nickname,
|
nickname: data.nickname,
|
||||||
avatarLoaded: false,
|
avatarLoaded: false,
|
||||||
activeOrderId: data.active_order_id ? data.active_order_id : null,
|
activeOrderId: data.active_order_id ? data.active_order_id : null,
|
||||||
referralCode: data.referral_code,
|
referralCode: data.referral_code,
|
||||||
earnedRewards: data.earned_rewards,
|
earnedRewards: data.earned_rewards,
|
||||||
lastOrderId: data.last_order_id ? data.last_order_id : null,
|
lastOrderId: data.last_order_id ? data.last_order_id : null,
|
||||||
stealthInvoices: data.wants_stealth,
|
stealthInvoices: data.wants_stealth,
|
||||||
})
|
})
|
||||||
:
|
: this.props.setAppState({
|
||||||
(this.props.setAppState({
|
nickname: data.nickname,
|
||||||
nickname: data.nickname,
|
token: token,
|
||||||
token: token,
|
avatarLoaded: false,
|
||||||
avatarLoaded: false,
|
activeOrderId: data.active_order_id ? data.active_order_id : null,
|
||||||
activeOrderId: data.active_order_id ? data.active_order_id : null,
|
lastOrderId: data.last_order_id ? data.last_order_id : null,
|
||||||
lastOrderId: data.last_order_id ? data.last_order_id : null,
|
referralCode: data.referral_code,
|
||||||
referralCode: data.referral_code,
|
earnedRewards: data.earned_rewards,
|
||||||
earnedRewards: data.earned_rewards,
|
stealthInvoices: data.wants_stealth,
|
||||||
stealthInvoices: data.wants_stealth,
|
}) &
|
||||||
})) & writeCookie("robot_token",token)
|
writeCookie('robot_token', token) &
|
||||||
& writeCookie("pub_key",data.public_key.split('\n').join('\\'))
|
writeCookie('pub_key', data.public_key.split('\n').join('\\')) &
|
||||||
& writeCookie("enc_priv_key",data.encrypted_private_key.split('\n').join('\\')))
|
writeCookie('enc_priv_key', data.encrypted_private_key.split('\n').join('\\'))) &
|
||||||
&
|
// If the robot has been found (recovered) we assume the token is backed up
|
||||||
// If the robot has been found (recovered) we assume the token is backed up
|
(data.found ? this.props.setAppState({ copiedToken: true }) : null);
|
||||||
(data.found ? this.props.setAppState({copiedToken:true}) : null)
|
}),
|
||||||
})
|
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
delGeneratedUser() {
|
delGeneratedUser() {
|
||||||
const requestOptions = {
|
const requestOptions = {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: {'Content-Type':'application/json', 'X-CSRFToken': getCookie('csrftoken')},
|
headers: { 'Content-Type': 'application/json', 'X-CSRFToken': getCookie('csrftoken') },
|
||||||
};
|
};
|
||||||
fetch("/api/user", requestOptions)
|
fetch('/api/user', requestOptions).then((response) => response.json());
|
||||||
.then((response) => response.json());
|
|
||||||
|
|
||||||
deleteCookie("sessionid");
|
deleteCookie('sessionid');
|
||||||
deleteCookie("robot_token");
|
deleteCookie('robot_token');
|
||||||
deleteCookie("pub_key");
|
deleteCookie('pub_key');
|
||||||
deleteCookie("enc_priv_key");
|
deleteCookie('enc_priv_key');
|
||||||
}
|
}
|
||||||
|
|
||||||
handleClickNewRandomToken=()=>{
|
handleClickNewRandomToken = () => {
|
||||||
var token = genBase62Token(36);
|
var token = genBase62Token(36);
|
||||||
this.setState({
|
this.setState({
|
||||||
token: token,
|
token: token,
|
||||||
tokenHasChanged: true,
|
tokenHasChanged: true,
|
||||||
});
|
});
|
||||||
this.props.setAppState({copiedToken: true})
|
this.props.setAppState({ copiedToken: true });
|
||||||
}
|
};
|
||||||
|
|
||||||
handleChangeToken=(e)=>{
|
handleChangeToken = (e) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
token: e.target.value.split(' ').join(''),
|
token: e.target.value.split(' ').join(''),
|
||||||
tokenHasChanged: true,
|
tokenHasChanged: true,
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
handleClickSubmitToken=()=>{
|
handleClickSubmitToken = () => {
|
||||||
this.delGeneratedUser();
|
this.delGeneratedUser();
|
||||||
this.getGeneratedUser(this.state.token);
|
this.getGeneratedUser(this.state.token);
|
||||||
this.setState({loadingRobot: true, tokenHasChanged: false});
|
this.setState({ loadingRobot: true, tokenHasChanged: false });
|
||||||
this.props.setAppState({avatarLoaded: false,
|
this.props.setAppState({
|
||||||
nickname: null,
|
avatarLoaded: false,
|
||||||
token: null,
|
nickname: null,
|
||||||
copiedToken: false,
|
token: null,
|
||||||
|
copiedToken: false,
|
||||||
lastOrderId: null,
|
lastOrderId: null,
|
||||||
activeOrderId: null});
|
activeOrderId: null,
|
||||||
}
|
});
|
||||||
|
};
|
||||||
|
|
||||||
handleClickOpenInfo = () => {
|
handleClickOpenInfo = () => {
|
||||||
this.setState({openInfo: true});
|
this.setState({ openInfo: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
handleCloseInfo = () => {
|
handleCloseInfo = () => {
|
||||||
this.setState({openInfo: false});
|
this.setState({ openInfo: false });
|
||||||
};
|
};
|
||||||
|
|
||||||
createJsonFile = () => {
|
createJsonFile = () => {
|
||||||
return ({
|
return {
|
||||||
"token":getCookie('robot_token'),
|
token: getCookie('robot_token'),
|
||||||
"token_shannon_entropy": this.state.shannon_entropy,
|
token_shannon_entropy: this.state.shannon_entropy,
|
||||||
"token_bit_entropy": this.state.bit_entropy,
|
token_bit_entropy: this.state.bit_entropy,
|
||||||
"public_key": getCookie('pub_key').split('\\').join('\n'),
|
public_key: getCookie('pub_key').split('\\').join('\n'),
|
||||||
"encrypted_private_key": getCookie('enc_priv_key').split('\\').join('\n'),
|
encrypted_private_key: getCookie('enc_priv_key').split('\\').join('\n'),
|
||||||
})
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { t, i18n} = this.props;
|
const { t, i18n } = this.props;
|
||||||
const fontSize = this.props.theme.typography.fontSize;
|
const fontSize = this.props.theme.typography.fontSize;
|
||||||
const fontSizeFactor = fontSize / 14; // to scale sizes, default fontSize is 14
|
const fontSizeFactor = fontSize / 14; // to scale sizes, default fontSize is 14
|
||||||
return (
|
return (
|
||||||
<Grid container spacing={1}>
|
<Grid container spacing={1}>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<div className='clickTrough'/>
|
<div className='clickTrough' />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} align="center" sx={{width:370 * fontSizeFactor, height: 260 * fontSizeFactor}}>
|
<Grid
|
||||||
{!this.state.loadingRobot && this.state.avatarUrl ?
|
item
|
||||||
|
xs={12}
|
||||||
|
align='center'
|
||||||
|
sx={{ width: 370 * fontSizeFactor, height: 260 * fontSizeFactor }}
|
||||||
|
>
|
||||||
|
{!this.state.loadingRobot && this.state.avatarUrl ? (
|
||||||
<div>
|
<div>
|
||||||
<Grid item xs={12} align="center">
|
<Grid item xs={12} align='center'>
|
||||||
<Typography component="h5" variant="h5">
|
<Typography component='h5' variant='h5'>
|
||||||
<b>{this.state.nickname && getCookie("sessionid") ?
|
<b>
|
||||||
<div style={{display:'flex', alignItems:'center', justifyContent:'center', flexWrap:'wrap', height: 45 * fontSizeFactor}}>
|
{this.state.nickname && getCookie('sessionid') ? (
|
||||||
<BoltIcon sx={{ color: "#fcba03", height: 33 * fontSizeFactor, width: 33 * fontSizeFactor}}/>
|
<div
|
||||||
<a>{this.state.nickname}</a>
|
style={{
|
||||||
<BoltIcon sx={{ color: "#fcba03", height: 33 * fontSizeFactor, width: 33 * fontSizeFactor}}/>
|
display: 'flex',
|
||||||
</div>
|
alignItems: 'center',
|
||||||
: ""}</b>
|
justifyContent: 'center',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
height: 45 * fontSizeFactor,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<BoltIcon
|
||||||
|
sx={{
|
||||||
|
color: '#fcba03',
|
||||||
|
height: 33 * fontSizeFactor,
|
||||||
|
width: 33 * fontSizeFactor,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<a>{this.state.nickname}</a>
|
||||||
|
<BoltIcon
|
||||||
|
sx={{
|
||||||
|
color: '#fcba03',
|
||||||
|
height: 33 * fontSizeFactor,
|
||||||
|
width: 33 * fontSizeFactor,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
''
|
||||||
|
)}
|
||||||
|
</b>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} align="center">
|
<Grid item xs={12} align='center'>
|
||||||
<Tooltip enterTouchDelay={0} title={t("This is your trading avatar")}>
|
<Tooltip enterTouchDelay={0} title={t('This is your trading avatar')}>
|
||||||
<div style={{ maxWidth: 200 * fontSizeFactor, maxHeight: 200 * fontSizeFactor}}>
|
<div style={{ maxWidth: 200 * fontSizeFactor, maxHeight: 200 * fontSizeFactor }}>
|
||||||
<SmoothImage
|
<SmoothImage
|
||||||
src={this.state.avatarUrl}
|
src={this.state.avatarUrl}
|
||||||
imageStyles={{borderRadius: "50%",
|
imageStyles={{
|
||||||
border: "2px solid #555",
|
borderRadius: '50%',
|
||||||
filter: "drop-shadow(1px 1px 1px #000000)",
|
border: '2px solid #555',
|
||||||
height: `${195*fontSizeFactor}px`,
|
filter: 'drop-shadow(1px 1px 1px #000000)',
|
||||||
width: `${200*fontSizeFactor}px`}}
|
height: `${195 * fontSizeFactor}px`,
|
||||||
/>
|
width: `${200 * fontSizeFactor}px`,
|
||||||
</div>
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<br/>
|
<br />
|
||||||
</Grid>
|
</Grid>
|
||||||
</div>
|
</div>
|
||||||
: <CircularProgress sx={{position: 'relative', top: 100, }}/>}
|
) : (
|
||||||
|
<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>
|
||||||
{
|
) : (
|
||||||
this.state.found ?
|
''
|
||||||
<Grid item xs={12} align="center">
|
)}
|
||||||
<Typography variant="subtitle2" color='primary'>
|
<Grid container align='center'>
|
||||||
{this.state.found ? t("A robot avatar was found, welcome back!"):null}<br/>
|
<Grid item xs={12} align='center'>
|
||||||
</Typography>
|
<TextField
|
||||||
</Grid>
|
sx={{ maxWidth: 280 * fontSizeFactor }}
|
||||||
:
|
error={this.state.bad_request ? true : false}
|
||||||
""
|
label={t('Store your token safely')}
|
||||||
}
|
required={true}
|
||||||
<Grid container align="center">
|
value={this.state.token}
|
||||||
<Grid item xs={12} align="center">
|
variant='standard'
|
||||||
<TextField sx={{maxWidth: 280 * fontSizeFactor}}
|
helperText={this.state.bad_request}
|
||||||
error={this.state.bad_request ? true : false}
|
size='small'
|
||||||
label={t("Store your token safely")}
|
onChange={this.handleChangeToken}
|
||||||
required={true}
|
onKeyPress={(e) => {
|
||||||
value={this.state.token}
|
if (e.key === 'Enter') {
|
||||||
variant='standard'
|
this.handleClickSubmitToken();
|
||||||
helperText={this.state.bad_request}
|
}
|
||||||
size='small'
|
}}
|
||||||
onChange={this.handleChangeToken}
|
InputProps={{
|
||||||
onKeyPress={(e) => {
|
startAdornment: (
|
||||||
if (e.key === 'Enter') {
|
<div
|
||||||
this.handleClickSubmitToken();
|
style={{
|
||||||
}
|
width: 50 * fontSizeFactor,
|
||||||
}}
|
minWidth: 50 * fontSizeFactor,
|
||||||
InputProps={{
|
position: 'relative',
|
||||||
startAdornment:
|
left: -6,
|
||||||
<div style={{width: 50*fontSizeFactor, minWidth: 50*fontSizeFactor, position:'relative',left:-6}}>
|
}}
|
||||||
|
>
|
||||||
<Grid container>
|
<Grid container>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Tooltip enterTouchDelay={250} title={t("Save token and PGP credentials to file")}>
|
<Tooltip
|
||||||
|
enterTouchDelay={250}
|
||||||
|
title={t('Save token and PGP credentials to file')}
|
||||||
|
>
|
||||||
<span>
|
<span>
|
||||||
<IconButton
|
<IconButton
|
||||||
color="primary"
|
color='primary'
|
||||||
disabled={!(getCookie('robot_token')==this.state.token) || !this.props.avatarLoaded}
|
disabled={
|
||||||
onClick={()=> saveAsJson(this.state.nickname+'.json', this.createJsonFile())}
|
!(getCookie('robot_token') == this.state.token) ||
|
||||||
|
!this.props.avatarLoaded
|
||||||
|
}
|
||||||
|
onClick={() =>
|
||||||
|
saveAsJson(this.state.nickname + '.json', this.createJsonFile())
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<DownloadIcon sx={{width: 22*fontSizeFactor, height: 22*fontSizeFactor}}/>
|
<DownloadIcon
|
||||||
</IconButton>
|
sx={{ width: 22 * fontSizeFactor, height: 22 * fontSizeFactor }}
|
||||||
|
/>
|
||||||
|
</IconButton>
|
||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Tooltip disableHoverListener enterTouchDelay={0} title={t("Copied!")}>
|
<Tooltip disableHoverListener enterTouchDelay={0} title={t('Copied!')}>
|
||||||
<IconButton
|
<IconButton
|
||||||
color={this.props.copiedToken ? "inherit":"primary"}
|
color={this.props.copiedToken ? 'inherit' : 'primary'}
|
||||||
disabled={!(getCookie('robot_token')==this.state.token) || !this.props.avatarLoaded}
|
disabled={
|
||||||
onClick={()=> (copyToClipboard(getCookie('robot_token')) & this.props.setAppState({copiedToken:true}))}
|
!(getCookie('robot_token') == this.state.token) ||
|
||||||
>
|
!this.props.avatarLoaded
|
||||||
<ContentCopy sx={{width: 18*fontSizeFactor, height: 18*fontSizeFactor}}/>
|
}
|
||||||
|
onClick={() =>
|
||||||
|
copyToClipboard(getCookie('robot_token')) &
|
||||||
|
this.props.setAppState({ copiedToken: true })
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<ContentCopy
|
||||||
|
sx={{ width: 18 * fontSizeFactor, height: 18 * fontSizeFactor }}
|
||||||
|
/>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</div>,
|
</div>
|
||||||
endAdornment:
|
),
|
||||||
<Tooltip enterTouchDelay={250} title={t("Generate a new token")}>
|
endAdornment: (
|
||||||
|
<Tooltip enterTouchDelay={250} title={t('Generate a new token')}>
|
||||||
<IconButton onClick={this.handleClickNewRandomToken}>
|
<IconButton onClick={this.handleClickNewRandomToken}>
|
||||||
<CasinoIcon sx={{width: 18*fontSizeFactor, height: 18*fontSizeFactor}}/>
|
<CasinoIcon
|
||||||
|
sx={{ width: 18 * fontSizeFactor, height: 18 * fontSizeFactor }}
|
||||||
|
/>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>,
|
</Tooltip>
|
||||||
}}
|
),
|
||||||
/>
|
}}
|
||||||
</Grid>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} align="center">
|
</Grid>
|
||||||
{this.state.tokenHasChanged ?
|
<Grid item xs={12} align='center'>
|
||||||
<Button type="submit" size='small' onClick= {this.handleClickSubmitToken}>
|
{this.state.tokenHasChanged ? (
|
||||||
<SmartToyIcon sx={{width: 18*fontSizeFactor, height: 18*fontSizeFactor}} />
|
<Button type='submit' size='small' onClick={this.handleClickSubmitToken}>
|
||||||
<span> {t("Generate Robot")}</span>
|
<SmartToyIcon sx={{ width: 18 * fontSizeFactor, height: 18 * fontSizeFactor }} />
|
||||||
|
<span> {t('Generate Robot')}</span>
|
||||||
</Button>
|
</Button>
|
||||||
:
|
) : (
|
||||||
<Tooltip enterTouchDelay={0} enterDelay={500} enterNextDelay={2000} title={t("You must enter a new token first")}>
|
<Tooltip
|
||||||
|
enterTouchDelay={0}
|
||||||
|
enterDelay={500}
|
||||||
|
enterNextDelay={2000}
|
||||||
|
title={t('You must enter a new token first')}
|
||||||
|
>
|
||||||
<div>
|
<div>
|
||||||
<Button disabled={true} type="submit" size='small' >
|
<Button disabled={true} type='submit' size='small'>
|
||||||
<SmartToyIcon sx={{width: 18*fontSizeFactor, height: 18*fontSizeFactor}} />
|
<SmartToyIcon sx={{ width: 18 * fontSizeFactor, height: 18 * fontSizeFactor }} />
|
||||||
<span>{t("Generate Robot")}</span>
|
<span>{t('Generate Robot')}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
}
|
)}
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} align="center">
|
<Grid item xs={12} align='center'>
|
||||||
<ButtonGroup variant="contained" aria-label="outlined primary button group">
|
<ButtonGroup variant='contained' aria-label='outlined primary button group'>
|
||||||
<Button disabled={this.state.loadingRobot || !(this.props.token ? getCookie('robot_token')==this.props.token : true )} color='primary' to='/make/' component={Link}>{t("Make Order")}</Button>
|
<Button
|
||||||
<Button color='inherit' style={{color: '#111111'}} onClick={this.handleClickOpenInfo}>{t("Info")}</Button>
|
disabled={
|
||||||
<InfoDialog open={Boolean(this.state.openInfo)} maxAmount='4,000,000' onClose = {this.handleCloseInfo}/>
|
this.state.loadingRobot ||
|
||||||
<Button disabled={this.state.loadingRobot || !(this.props.token ? getCookie('robot_token')==this.props.token : true )} color='secondary' to='/book/' component={Link}>{t("View Book")}</Button>
|
!(this.props.token ? getCookie('robot_token') == this.props.token : true)
|
||||||
</ButtonGroup>
|
}
|
||||||
</Grid>
|
color='primary'
|
||||||
|
to='/make/'
|
||||||
|
component={Link}
|
||||||
|
>
|
||||||
|
{t('Make Order')}
|
||||||
|
</Button>
|
||||||
|
<Button color='inherit' style={{ color: '#111111' }} onClick={this.handleClickOpenInfo}>
|
||||||
|
{t('Info')}
|
||||||
|
</Button>
|
||||||
|
<InfoDialog
|
||||||
|
open={Boolean(this.state.openInfo)}
|
||||||
|
maxAmount='4,000,000'
|
||||||
|
onClose={this.handleCloseInfo}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
disabled={
|
||||||
|
this.state.loadingRobot ||
|
||||||
|
!(this.props.token ? getCookie('robot_token') == this.props.token : true)
|
||||||
|
}
|
||||||
|
color='secondary'
|
||||||
|
to='/book/'
|
||||||
|
component={Link}
|
||||||
|
>
|
||||||
|
{t('View Book')}
|
||||||
|
</Button>
|
||||||
|
</ButtonGroup>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<Grid item xs={12} align="center" sx={{width: 370*fontSizeFactor}}>
|
<Grid item xs={12} align='center' sx={{ width: 370 * fontSizeFactor }}>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<div style={{height: 30*fontSizeFactor}}/>
|
<div style={{ height: 30 * fontSizeFactor }} />
|
||||||
</Grid>
|
|
||||||
<div style={{width: 370*fontSizeFactor, left: 30*fontSizeFactor}}>
|
|
||||||
<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: 72 * fontSizeFactor, width: 72 * fontSizeFactor}}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</div>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<div style={{ width: 370 * fontSizeFactor, left: 30 * fontSizeFactor }}>
|
||||||
|
<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: 72 * fontSizeFactor, width: 72 * fontSizeFactor }}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</div>
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import i18n from "i18next";
|
import i18n from 'i18next';
|
||||||
import LanguageDetector from "i18next-browser-languagedetector";
|
import LanguageDetector from 'i18next-browser-languagedetector';
|
||||||
import { initReactI18next } from "react-i18next";
|
import { initReactI18next } from 'react-i18next';
|
||||||
import HttpApi from 'i18next-http-backend';
|
import HttpApi from 'i18next-http-backend';
|
||||||
|
|
||||||
// import translationEN from "../../static/locales/en.json";
|
// import translationEN from "../../static/locales/en.json";
|
||||||
@ -20,49 +20,49 @@ i18n
|
|||||||
.use(LanguageDetector)
|
.use(LanguageDetector)
|
||||||
.use(initReactI18next)
|
.use(initReactI18next)
|
||||||
.init({
|
.init({
|
||||||
// resources: {
|
// resources: {
|
||||||
// en: {translations: translationEN},
|
// en: {translations: translationEN},
|
||||||
// es: {translations: translationES},
|
// es: {translations: translationES},
|
||||||
// ru: {translations: translationRU},
|
// ru: {translations: translationRU},
|
||||||
// de: {translations: translationDE},
|
// de: {translations: translationDE},
|
||||||
// // zh: {translations: translationZH},
|
// // zh: {translations: translationZH},
|
||||||
// pl: {translations: translationPL},
|
// pl: {translations: translationPL},
|
||||||
// fr: {translations: translationFR},
|
// fr: {translations: translationFR},
|
||||||
// ca: {translations: translationCA},
|
// ca: {translations: translationCA},
|
||||||
// it: {translations: translationIT},
|
// it: {translations: translationIT},
|
||||||
// pt: {translations: translationPT},
|
// pt: {translations: translationPT},
|
||||||
// eu: {translations: translationEU},
|
// eu: {translations: translationEU},
|
||||||
// sv: {translations: translationSV},
|
// sv: {translations: translationSV},
|
||||||
// cs: {translations: translationCS},
|
// cs: {translations: translationCS},
|
||||||
// th: {translations: translationCS},
|
// th: {translations: translationCS},
|
||||||
// },
|
// },
|
||||||
|
|
||||||
backend:{
|
|
||||||
loadPath: '/static/locales/{{lng}}.json',
|
|
||||||
allowMultiLoading: false, // set loadPath: '/locales/resources.json?lng={{lng}}&ns={{ns}}' to adapt to multiLoading
|
|
||||||
crossDomain: false,
|
|
||||||
withCredentials: false,
|
|
||||||
overrideMimeType: false,
|
|
||||||
reloadInterval: false // can be used to reload resources in a specific interval (useful in server environments)
|
|
||||||
},
|
|
||||||
|
|
||||||
fallbackLng: "en",
|
backend: {
|
||||||
debug: false,
|
loadPath: '/static/locales/{{lng}}.json',
|
||||||
|
allowMultiLoading: false, // set loadPath: '/locales/resources.json?lng={{lng}}&ns={{ns}}' to adapt to multiLoading
|
||||||
|
crossDomain: false,
|
||||||
|
withCredentials: false,
|
||||||
|
overrideMimeType: false,
|
||||||
|
reloadInterval: false, // can be used to reload resources in a specific interval (useful in server environments)
|
||||||
|
},
|
||||||
|
|
||||||
// have a common namespace used around the full app
|
fallbackLng: 'en',
|
||||||
ns: ["translations"],
|
debug: false,
|
||||||
defaultNS: "translations",
|
|
||||||
|
|
||||||
keySeparator: false, // we use content as keys
|
// have a common namespace used around the full app
|
||||||
|
ns: ['translations'],
|
||||||
|
defaultNS: 'translations',
|
||||||
|
|
||||||
interpolation: {
|
keySeparator: false, // we use content as keys
|
||||||
escapeValue: false,
|
|
||||||
formatSeparator: ","
|
|
||||||
},
|
|
||||||
|
|
||||||
react: {
|
|
||||||
useSuspense: false,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default i18n;
|
interpolation: {
|
||||||
|
escapeValue: false,
|
||||||
|
formatSeparator: ',',
|
||||||
|
},
|
||||||
|
|
||||||
|
react: {
|
||||||
|
useSuspense: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default i18n;
|
||||||
|
File diff suppressed because one or more lines are too long
@ -1,86 +1,86 @@
|
|||||||
export const paymentMethods = [
|
export const paymentMethods = [
|
||||||
{name: "Revolut",icon:'revolut'},
|
{ name: 'Revolut', icon: 'revolut' },
|
||||||
{name: "CashApp",icon:'cashapp'},
|
{ name: 'CashApp', icon: 'cashapp' },
|
||||||
{name: "Zelle",icon:'zelle'},
|
{ name: 'Zelle', icon: 'zelle' },
|
||||||
{name: "Strike",icon:'strike'},
|
{ name: 'Strike', icon: 'strike' },
|
||||||
{name: "WeChat Pay", icon: 'wechatpay'},
|
{ name: 'WeChat Pay', icon: 'wechatpay' },
|
||||||
{name: "Rebellion",icon:'rebellion'},
|
{ name: 'Rebellion', icon: 'rebellion' },
|
||||||
{name: "Instant SEPA", icon:'sepa'},
|
{ name: 'Instant SEPA', icon: 'sepa' },
|
||||||
{name: "Interac e-Transfer",icon:'interac'},
|
{ name: 'Interac e-Transfer', icon: 'interac' },
|
||||||
{name: "Wise",icon:'wise'},
|
{ name: 'Wise', icon: 'wise' },
|
||||||
{name: "Venmo",icon:'venmo'},
|
{ name: 'Venmo', icon: 'venmo' },
|
||||||
{name: "Faster Payments",icon:'faster'},
|
{ name: 'Faster Payments', icon: 'faster' },
|
||||||
{name: "Paypal Friends & Family",icon:'paypal'},
|
{ name: 'Paypal Friends & Family', icon: 'paypal' },
|
||||||
{name: "LINE Pay",icon:'linepay'},
|
{ name: 'LINE Pay', icon: 'linepay' },
|
||||||
{name: "PromptPay",icon:'promptpay'},
|
{ name: 'PromptPay', icon: 'promptpay' },
|
||||||
{name: "Bizum",icon:'bizum'},
|
{ name: 'Bizum', icon: 'bizum' },
|
||||||
{name: "N26",icon:'n26'},
|
{ name: 'N26', icon: 'n26' },
|
||||||
{name: "Tinkoff",icon:'tinkoff'},
|
{ name: 'Tinkoff', icon: 'tinkoff' },
|
||||||
{name: "TWINT",icon:'twint'},
|
{ name: 'TWINT', icon: 'twint' },
|
||||||
{name: "BLIK",icon:'blik'},
|
{ name: 'BLIK', icon: 'blik' },
|
||||||
{name: "MBWay",icon:'mbway'},
|
{ name: 'MBWay', icon: 'mbway' },
|
||||||
{name: "W1TTY",icon:'w1tty'},
|
{ name: 'W1TTY', icon: 'w1tty' },
|
||||||
{name: "Verse",icon:'verse'},
|
{ name: 'Verse', icon: 'verse' },
|
||||||
{name: "Paysera",icon:'paysera'},
|
{ name: 'Paysera', icon: 'paysera' },
|
||||||
{name: "Amazon GiftCard",icon:'amazon'},
|
{ name: 'Amazon GiftCard', icon: 'amazon' },
|
||||||
{name: "Ozon GiftCard",icon:'ozon'},
|
{ name: 'Ozon GiftCard', icon: 'ozon' },
|
||||||
{name: "AliPay", icon: 'alipay'},
|
{ name: 'AliPay', icon: 'alipay' },
|
||||||
{name: "GPay", icon: 'gpay'},
|
{ name: 'GPay', icon: 'gpay' },
|
||||||
{name: "Bancolombia",icon:'bancolombia'},
|
{ name: 'Bancolombia', icon: 'bancolombia' },
|
||||||
{name: "Pago Movil BDV",icon:'pagomovilbdv'},
|
{ name: 'Pago Movil BDV', icon: 'pagomovilbdv' },
|
||||||
{name: "SPEI",icon:'spei'},
|
{ name: 'SPEI', icon: 'spei' },
|
||||||
{name: "PIX",icon:'pix'},
|
{ name: 'PIX', icon: 'pix' },
|
||||||
{name: "PayID",icon:'payid'},
|
{ name: 'PayID', icon: 'payid' },
|
||||||
{name: "Paysafe",icon:'paysafe'},
|
{ name: 'Paysafe', icon: 'paysafe' },
|
||||||
{name: "Sberbank",icon:'sberbank'},
|
{ name: 'Sberbank', icon: 'sberbank' },
|
||||||
{name: "PhonePe",icon:'phonepe'},
|
{ name: 'PhonePe', icon: 'phonepe' },
|
||||||
{name: "OVO",icon:'ovo'},
|
{ name: 'OVO', icon: 'ovo' },
|
||||||
{name: "HalCash",icon:'halcash'},
|
{ name: 'HalCash', icon: 'halcash' },
|
||||||
{name: "Vivid",icon:'vivid'},
|
{ name: 'Vivid', icon: 'vivid' },
|
||||||
{name: "Google Play Gift Code",icon:'googleplay'},
|
{ name: 'Google Play Gift Code', icon: 'googleplay' },
|
||||||
{name: "Apple Pay",icon:'applepay'},
|
{ name: 'Apple Pay', icon: 'applepay' },
|
||||||
{name: "Steam",icon:'steam'},
|
{ name: 'Steam', icon: 'steam' },
|
||||||
{name: "Nequi",icon:'nequi'},
|
{ name: 'Nequi', icon: 'nequi' },
|
||||||
{name: "ShakePay",icon:'shakepay'},
|
{ name: 'ShakePay', icon: 'shakepay' },
|
||||||
{name: "DaviPlata",icon:'daviplata'},
|
{ name: 'DaviPlata', icon: 'daviplata' },
|
||||||
{name: "CoDi",icon:'codi'},
|
{ name: 'CoDi', icon: 'codi' },
|
||||||
{name: "TaiwanPay",icon:'taiwanpay'},
|
{ name: 'TaiwanPay', icon: 'taiwanpay' },
|
||||||
{name: "MaiCoin",icon:'maicoin'},
|
{ name: 'MaiCoin', icon: 'maicoin' },
|
||||||
{name: "GoPay", icon: 'gopay'},
|
{ name: 'GoPay', icon: 'gopay' },
|
||||||
{name: "MercadoPago",icon:'mercadopago'},
|
{ name: 'MercadoPago', icon: 'mercadopago' },
|
||||||
{name: "Monero",icon:'monero'},
|
{ name: 'Monero', icon: 'monero' },
|
||||||
{name: "USDT",icon:'usdt'},
|
{ name: 'USDT', icon: 'usdt' },
|
||||||
{name: "Airtel Money",icon:'airtel'},
|
{ name: 'Airtel Money', icon: 'airtel' },
|
||||||
{name: "MTN Money",icon:'mtn'},
|
{ name: 'MTN Money', icon: 'mtn' },
|
||||||
{name: "M-Pesa",icon:'mpesa'},
|
{ name: 'M-Pesa', icon: 'mpesa' },
|
||||||
{name: "UPI",icon:'upi'},
|
{ name: 'UPI', icon: 'upi' },
|
||||||
{name: "MoMo",icon:'momo'},
|
{ name: 'MoMo', icon: 'momo' },
|
||||||
{name: "Tigo Pesa",icon:'tigopesa'},
|
{ name: 'Tigo Pesa', icon: 'tigopesa' },
|
||||||
{name: "Cash F2F",icon:'cash'},
|
{ name: 'Cash F2F', icon: 'cash' },
|
||||||
{name: "Amazon USA GiftCard",icon:'amazonus'},
|
{ name: 'Amazon USA GiftCard', icon: 'amazonus' },
|
||||||
{name: "Amazon DE GiftCard",icon:'amazonde'},
|
{ name: 'Amazon DE GiftCard', icon: 'amazonde' },
|
||||||
{name: "Amazon AU GiftCard",icon:'amazonau'},
|
{ name: 'Amazon AU GiftCard', icon: 'amazonau' },
|
||||||
{name: "Amazon SA GiftCard",icon:'amazonsa'},
|
{ name: 'Amazon SA GiftCard', icon: 'amazonsa' },
|
||||||
{name: "Amazon ES GiftCard",icon:'amazones'},
|
{ name: 'Amazon ES GiftCard', icon: 'amazones' },
|
||||||
{name: "Amazon CA GiftCard",icon:'amazonca'},
|
{ name: 'Amazon CA GiftCard', icon: 'amazonca' },
|
||||||
{name: "Amazon CN GiftCard",icon:'amazoncn'},
|
{ name: 'Amazon CN GiftCard', icon: 'amazoncn' },
|
||||||
{name: "Amazon AE GiftCard",icon:'amazonae'},
|
{ name: 'Amazon AE GiftCard', icon: 'amazonae' },
|
||||||
{name: "Amazon FR GiftCard",icon:'amazonfr'},
|
{ name: 'Amazon FR GiftCard', icon: 'amazonfr' },
|
||||||
{name: "Amazon NL GiftCard",icon:'amazonnl'},
|
{ name: 'Amazon NL GiftCard', icon: 'amazonnl' },
|
||||||
{name: "Amazon IN GiftCard",icon:'amazonin'},
|
{ name: 'Amazon IN GiftCard', icon: 'amazonin' },
|
||||||
{name: "Amazon IT GiftCard",icon:'amazonit'},
|
{ name: 'Amazon IT GiftCard', icon: 'amazonit' },
|
||||||
{name: "Amazon JP GiftCard",icon:'amazonjp'},
|
{ name: 'Amazon JP GiftCard', icon: 'amazonjp' },
|
||||||
{name: "Amazon MX GiftCard",icon:'amazonmx'},
|
{ name: 'Amazon MX GiftCard', icon: 'amazonmx' },
|
||||||
{name: "Amazon PL GiftCard",icon:'amazonpl'},
|
{ name: 'Amazon PL GiftCard', icon: 'amazonpl' },
|
||||||
{name: "Amazon UK GiftCard",icon:'amazonuk'},
|
{ name: 'Amazon UK GiftCard', icon: 'amazonuk' },
|
||||||
{name: "Amazon SE GiftCard",icon:'amazonse'},
|
{ name: 'Amazon SE GiftCard', icon: 'amazonse' },
|
||||||
{name: "Amazon SG GiftCard",icon:'amazonsg'},
|
{ name: 'Amazon SG GiftCard', icon: 'amazonsg' },
|
||||||
{name: "Amazon TR GiftCard",icon:'amazontr'},
|
{ name: 'Amazon TR GiftCard', icon: 'amazontr' },
|
||||||
];
|
];
|
||||||
|
|
||||||
export const swapDestinations = [
|
export const swapDestinations = [
|
||||||
{name: "On-Chain BTC",icon:'onchain'},
|
{ name: 'On-Chain BTC', icon: 'onchain' },
|
||||||
{name: "RBTC",icon:'rbtc'},
|
{ name: 'RBTC', icon: 'rbtc' },
|
||||||
{name: "LBTC",icon:'lbtc'},
|
{ name: 'LBTC', icon: 'lbtc' },
|
||||||
{name: "WBTC",icon:'wbtc'},
|
{ name: 'WBTC', icon: 'wbtc' },
|
||||||
];
|
];
|
||||||
|
@ -1 +1 @@
|
|||||||
import App from "./components/App";
|
import App from './components/App';
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
export interface Limit {
|
export interface Limit {
|
||||||
code: string,
|
code: string;
|
||||||
price: number,
|
price: number;
|
||||||
min_amount: number,
|
min_amount: number;
|
||||||
max_amount: number,
|
max_amount: number;
|
||||||
max_bondless_amount: number
|
max_bondless_amount: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LimitList {
|
export interface LimitList {
|
||||||
[currencyCode: string]: Limit
|
[currencyCode: string]: Limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Limit
|
export default Limit;
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
export interface Order {
|
export interface Order {
|
||||||
id: number,
|
id: number;
|
||||||
created_at: Date,
|
created_at: Date;
|
||||||
expires_at: Date,
|
expires_at: Date;
|
||||||
type: number,
|
type: number;
|
||||||
currency: number,
|
currency: number;
|
||||||
amount: string,
|
amount: string;
|
||||||
base_amount?: number,
|
base_amount?: number;
|
||||||
has_range: boolean,
|
has_range: boolean;
|
||||||
min_amount: number,
|
min_amount: number;
|
||||||
max_amount: number,
|
max_amount: number;
|
||||||
payment_method: string,
|
payment_method: string;
|
||||||
is_explicit: false,
|
is_explicit: false;
|
||||||
premium: number,
|
premium: number;
|
||||||
satoshis: number,
|
satoshis: number;
|
||||||
bondless_taker: boolean,
|
bondless_taker: boolean;
|
||||||
maker: number,
|
maker: number;
|
||||||
escrow_duration: number,
|
escrow_duration: number;
|
||||||
maker_nick: string,
|
maker_nick: string;
|
||||||
price: number,
|
price: number;
|
||||||
maker_status: "Active" | "Seen recently" | "Inactive"
|
maker_status: 'Active' | 'Seen recently' | 'Inactive';
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Order
|
export default Order;
|
||||||
|
@ -1,24 +1,25 @@
|
|||||||
export function copyToClipboard(textToCopy) {
|
export function copyToClipboard(textToCopy) {
|
||||||
// navigator clipboard api needs a secure context (https)
|
// navigator clipboard api needs a secure context (https)
|
||||||
// this function attempts to copy also on http contexts
|
// this function attempts to copy also on http contexts
|
||||||
// useful on the http i2p site and on torified browsers
|
// useful on the http i2p site and on torified browsers
|
||||||
if (navigator.clipboard && window.isSecureContext) {
|
if (navigator.clipboard && window.isSecureContext) {
|
||||||
// navigator clipboard api method'
|
// navigator clipboard api method'
|
||||||
return navigator.clipboard.writeText(textToCopy);
|
return navigator.clipboard.writeText(textToCopy);
|
||||||
} else {
|
} else {
|
||||||
// text area method
|
// text area method
|
||||||
let textArea = document.createElement("textarea");
|
let textArea = document.createElement('textarea');
|
||||||
textArea.value = textToCopy;
|
textArea.value = textToCopy;
|
||||||
// make the textarea out of viewport
|
// make the textarea out of viewport
|
||||||
textArea.style.position = "fixed";
|
textArea.style.position = 'fixed';
|
||||||
textArea.style.left = "-999999px";
|
textArea.style.left = '-999999px';
|
||||||
textArea.style.top = "-999999px";
|
textArea.style.top = '-999999px';
|
||||||
document.body.appendChild(textArea);
|
document.body.appendChild(textArea);
|
||||||
textArea.focus();
|
textArea.focus();
|
||||||
textArea.select();
|
textArea.select();
|
||||||
return new Promise((res, rej) => {
|
return new Promise((res, rej) => {
|
||||||
// here the magic happens
|
// here the magic happens
|
||||||
document.execCommand('copy') ? res() : rej();
|
document.execCommand('copy') ? res() : rej();
|
||||||
textArea.remove();
|
textArea.remove();
|
||||||
});
|
});
|
||||||
}}
|
}
|
||||||
|
}
|
||||||
|
@ -5,7 +5,7 @@ export const getCookie = (name) => {
|
|||||||
for (let i = 0; i < cookies.length; i++) {
|
for (let i = 0; i < cookies.length; i++) {
|
||||||
const cookie = cookies[i].trim();
|
const cookie = cookies[i].trim();
|
||||||
// Does this cookie string begin with the name we want?
|
// Does this cookie string begin with the name we want?
|
||||||
if (cookie.substring(0, name.length + 1) === (name + '=')) {
|
if (cookie.substring(0, name.length + 1) === name + '=') {
|
||||||
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -14,10 +14,10 @@ export const getCookie = (name) => {
|
|||||||
return cookieValue;
|
return cookieValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const writeCookie = (key,value) => {
|
export const writeCookie = (key, value) => {
|
||||||
document.cookie=`${key}=${value};path=/;SameSite=Strict`;
|
document.cookie = `${key}=${value};path=/;SameSite=Strict`;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const deleteCookie = (name) => {
|
export const deleteCookie = (name) => {
|
||||||
document.cookie = `${name}= ; expires = Thu, 01 Jan 1970 00:00:00 GMT`
|
document.cookie = `${name}= ; expires = Thu, 01 Jan 1970 00:00:00 GMT`;
|
||||||
}
|
};
|
||||||
|
@ -4,4 +4,4 @@ export const median = (arr: number[]) => {
|
|||||||
return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2;
|
return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default median
|
export default median;
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import {
|
import {
|
||||||
generateKey,
|
generateKey,
|
||||||
readKey,
|
readKey,
|
||||||
readPrivateKey,
|
readPrivateKey,
|
||||||
decryptKey,
|
decryptKey,
|
||||||
encrypt,
|
encrypt,
|
||||||
decrypt,
|
decrypt,
|
||||||
createMessage,
|
createMessage,
|
||||||
readMessage
|
readMessage,
|
||||||
} from 'openpgp/lightweight';
|
} from 'openpgp/lightweight';
|
||||||
import { sha256 } from 'js-sha256';
|
import { sha256 } from 'js-sha256';
|
||||||
|
|
||||||
@ -16,60 +16,69 @@ export async function genKey(highEntropyToken) {
|
|||||||
const keyPair = await generateKey({
|
const keyPair = await generateKey({
|
||||||
type: 'ecc', // Type of the key, defaults to ECC
|
type: 'ecc', // Type of the key, defaults to ECC
|
||||||
curve: 'curve25519', // ECC curve name, defaults to curve25519
|
curve: 'curve25519', // ECC curve name, defaults to curve25519
|
||||||
userIDs: [{name: 'RoboSats ID '+ sha256(sha256(highEntropyToken))}], //Ideally it would be the avatar nickname, but the nickname is generated only after submission. The second SHA256 can be converted into the Nickname using nick_generator package.
|
userIDs: [{ name: 'RoboSats ID ' + sha256(sha256(highEntropyToken)) }], //Ideally it would be the avatar nickname, but the nickname is generated only after submission. The second SHA256 can be converted into the Nickname using nick_generator package.
|
||||||
passphrase: highEntropyToken,
|
passphrase: highEntropyToken,
|
||||||
format: 'armored',
|
format: 'armored',
|
||||||
date: d.setDate(d.getDate()-1) // One day of offset. Helps reducing errors due to client's system time being in the future.
|
date: d.setDate(d.getDate() - 1), // One day of offset. Helps reducing errors due to client's system time being in the future.
|
||||||
})
|
});
|
||||||
|
|
||||||
return {publicKeyArmored: keyPair.publicKey, encryptedPrivateKeyArmored: keyPair.privateKey}
|
return { publicKeyArmored: keyPair.publicKey, encryptedPrivateKeyArmored: keyPair.privateKey };
|
||||||
};
|
}
|
||||||
|
|
||||||
// Encrypt and sign a message
|
// Encrypt and sign a message
|
||||||
export async function encryptMessage(plaintextMessage, ownPublicKeyArmored, peerPublicKeyArmored, privateKeyArmored, passphrase) {
|
export async function encryptMessage(
|
||||||
|
plaintextMessage,
|
||||||
|
ownPublicKeyArmored,
|
||||||
|
peerPublicKeyArmored,
|
||||||
|
privateKeyArmored,
|
||||||
|
passphrase,
|
||||||
|
) {
|
||||||
const ownPublicKey = await readKey({ armoredKey: ownPublicKeyArmored });
|
const ownPublicKey = await readKey({ armoredKey: ownPublicKeyArmored });
|
||||||
const peerPublicKey = await readKey({ armoredKey: peerPublicKeyArmored });
|
const peerPublicKey = await readKey({ armoredKey: peerPublicKeyArmored });
|
||||||
const privateKey = await decryptKey({
|
const privateKey = await decryptKey({
|
||||||
privateKey: await readPrivateKey({ armoredKey: privateKeyArmored }),
|
privateKey: await readPrivateKey({ armoredKey: privateKeyArmored }),
|
||||||
passphrase
|
passphrase,
|
||||||
});
|
});
|
||||||
|
|
||||||
const d = new Date();
|
const d = new Date();
|
||||||
const encryptedMessage = await encrypt({
|
const encryptedMessage = await encrypt({
|
||||||
message: await createMessage({ text: plaintextMessage }), // input as Message object, message must be string
|
message: await createMessage({ text: plaintextMessage }), // input as Message object, message must be string
|
||||||
encryptionKeys: [ ownPublicKey, peerPublicKey ],
|
encryptionKeys: [ownPublicKey, peerPublicKey],
|
||||||
signingKeys: privateKey, // optional
|
signingKeys: privateKey, // optional
|
||||||
date: d.setDate(d.getDate()-1) // One day of offset, avoids verification issue due to clock mismatch
|
date: d.setDate(d.getDate() - 1), // One day of offset, avoids verification issue due to clock mismatch
|
||||||
});
|
});
|
||||||
|
|
||||||
return encryptedMessage; // '-----BEGIN PGP MESSAGE ... END PGP MESSAGE-----'
|
return encryptedMessage; // '-----BEGIN PGP MESSAGE ... END PGP MESSAGE-----'
|
||||||
};
|
}
|
||||||
|
|
||||||
// Decrypt and check signature of a message
|
// Decrypt and check signature of a message
|
||||||
export async function decryptMessage(encryptedMessage, publicKeyArmored, privateKeyArmored, passphrase) {
|
export async function decryptMessage(
|
||||||
|
encryptedMessage,
|
||||||
|
publicKeyArmored,
|
||||||
|
privateKeyArmored,
|
||||||
|
passphrase,
|
||||||
|
) {
|
||||||
const publicKey = await readKey({ armoredKey: publicKeyArmored });
|
const publicKey = await readKey({ armoredKey: publicKeyArmored });
|
||||||
const privateKey = await decryptKey({
|
const privateKey = await decryptKey({
|
||||||
privateKey: await readPrivateKey({ armoredKey: privateKeyArmored }),
|
privateKey: await readPrivateKey({ armoredKey: privateKeyArmored }),
|
||||||
passphrase
|
passphrase,
|
||||||
});
|
});
|
||||||
|
|
||||||
const message = await readMessage({
|
const message = await readMessage({
|
||||||
armoredMessage: encryptedMessage // parse armored message
|
armoredMessage: encryptedMessage, // parse armored message
|
||||||
});
|
});
|
||||||
const { data: decrypted, signatures } = await decrypt({
|
const { data: decrypted, signatures } = await decrypt({
|
||||||
message,
|
message,
|
||||||
verificationKeys: publicKey, // optional
|
verificationKeys: publicKey, // optional
|
||||||
decryptionKeys: privateKey
|
decryptionKeys: privateKey,
|
||||||
});
|
});
|
||||||
|
|
||||||
// check signature validity (signed messages only)
|
// check signature validity (signed messages only)
|
||||||
try {
|
try {
|
||||||
await signatures[0].verified; // throws on invalid signature
|
await signatures[0].verified; // throws on invalid signature
|
||||||
console.log('Signature is valid');
|
console.log('Signature is valid');
|
||||||
return {decryptedMessage: decrypted, validSignature: true}
|
return { decryptedMessage: decrypted, validSignature: true };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return {decryptedMessage: decrypted, validSignature: false};
|
return { decryptedMessage: decrypted, validSignature: false };
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
@ -1,45 +1,45 @@
|
|||||||
import { pn, amountToString } from "./prettyNumbers";
|
import { pn, amountToString } from './prettyNumbers';
|
||||||
|
|
||||||
describe("prettyNumbers", () => {
|
describe('prettyNumbers', () => {
|
||||||
test("pn()", () => {
|
test('pn()', () => {
|
||||||
[
|
[
|
||||||
{input: null, output: undefined},
|
{ input: null, output: undefined },
|
||||||
{input: undefined, output: undefined},
|
{ input: undefined, output: undefined },
|
||||||
{input: 0, output: "0"},
|
{ input: 0, output: '0' },
|
||||||
{input: 1, output: "1"},
|
{ input: 1, output: '1' },
|
||||||
{input: 2, output: "2"},
|
{ input: 2, output: '2' },
|
||||||
{input: 10, output: "10"},
|
{ input: 10, output: '10' },
|
||||||
{input: 11, output: "11"},
|
{ input: 11, output: '11' },
|
||||||
{input: 11.0, output: "11"},
|
{ input: 11.0, output: '11' },
|
||||||
{input: 12.0, output: "12"},
|
{ input: 12.0, output: '12' },
|
||||||
{input: 100.50, output: "100.5"},
|
{ input: 100.5, output: '100.5' },
|
||||||
{input: 224.56, output: "224.56"},
|
{ input: 224.56, output: '224.56' },
|
||||||
{input: 1567, output: "1,567"},
|
{ input: 1567, output: '1,567' },
|
||||||
{input: 15678, output: "15,678"},
|
{ input: 15678, output: '15,678' },
|
||||||
{input: 2984.99, output: "2,984.99"},
|
{ input: 2984.99, output: '2,984.99' },
|
||||||
{input: 100000.00, output: "100,000"},
|
{ input: 100000.0, output: '100,000' },
|
||||||
].forEach((it) => {
|
].forEach((it) => {
|
||||||
const response = pn(it.input);
|
const response = pn(it.input);
|
||||||
expect(response).toBe(it.output);
|
expect(response).toBe(it.output);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
describe("amountToString", () => {
|
describe('amountToString', () => {
|
||||||
test("pn()", () => {
|
test('pn()', () => {
|
||||||
[
|
[
|
||||||
{input: null, output: "NaN"},
|
{ input: null, output: 'NaN' },
|
||||||
{input: undefined, output: "NaN"},
|
{ input: undefined, output: 'NaN' },
|
||||||
{input: ["", false, 50, 150] , output: "0"},
|
{ input: ['', false, 50, 150], output: '0' },
|
||||||
{input: ["100.00", false, 50, 150] , output: "100"},
|
{ input: ['100.00', false, 50, 150], output: '100' },
|
||||||
{input: ["100.00", true, undefined, undefined] , output: "NaN-NaN"},
|
{ input: ['100.00', true, undefined, undefined], output: 'NaN-NaN' },
|
||||||
{input: ["100.00", true, undefined, 150] , output: "NaN-150"},
|
{ input: ['100.00', true, undefined, 150], output: 'NaN-150' },
|
||||||
{input: ["100.00", true, 50, undefined] , output: "50-NaN"},
|
{ input: ['100.00', true, 50, undefined], output: '50-NaN' },
|
||||||
{input: ["100.00", true, 50, 150] , output: "50-150"},
|
{ input: ['100.00', true, 50, 150], output: '50-150' },
|
||||||
].forEach((it) => {
|
].forEach((it) => {
|
||||||
const params: any[] = it.input || []
|
const params: any[] = it.input || [];
|
||||||
const response = amountToString(params[0],params[1],params[2],params[3]);
|
const response = amountToString(params[0], params[1], params[2], params[3]);
|
||||||
expect(response).toBe(it.output);
|
expect(response).toBe(it.output);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
|
@ -3,21 +3,27 @@ export const pn = (value?: number | null): string | undefined => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const parts = value.toString().split(".");
|
const parts = value.toString().split('.');
|
||||||
|
|
||||||
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||||
|
|
||||||
return parts.join(".");
|
return parts.join('.');
|
||||||
};
|
};
|
||||||
|
|
||||||
export const amountToString: (amount: string, has_range: boolean , min_amount: number, max_amount: number) => string =
|
export const amountToString: (
|
||||||
(amount, has_range, min_amount, max_amount) => {
|
amount: string,
|
||||||
if (has_range){
|
has_range: boolean,
|
||||||
return pn(parseFloat(Number(min_amount).toPrecision(4))) +
|
min_amount: number,
|
||||||
'-' +
|
max_amount: number,
|
||||||
pn(parseFloat(Number(max_amount).toPrecision(4)))
|
) => string = (amount, has_range, min_amount, max_amount) => {
|
||||||
|
if (has_range) {
|
||||||
|
return (
|
||||||
|
pn(parseFloat(Number(min_amount).toPrecision(4))) +
|
||||||
|
'-' +
|
||||||
|
pn(parseFloat(Number(max_amount).toPrecision(4)))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return pn(parseFloat(Number(amount).toPrecision(4))) || ""
|
return pn(parseFloat(Number(amount).toPrecision(4))) || '';
|
||||||
}
|
};
|
||||||
|
|
||||||
export default pn
|
export default pn;
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
/* function to save DATA as text from browser
|
/* function to save DATA as text from browser
|
||||||
* @param {String} file -- file name to save to
|
* @param {String} file -- file name to save to
|
||||||
* @param {filename} data -- object to save
|
* @param {filename} data -- object to save
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const saveAsJson = (filename, dataObjToWrite) => {
|
export const saveAsJson = (filename, dataObjToWrite) => {
|
||||||
const blob = new Blob([JSON.stringify(dataObjToWrite, null, 2)], { type: "text/json" });
|
const blob = new Blob([JSON.stringify(dataObjToWrite, null, 2)], { type: 'text/json' });
|
||||||
const link = document.createElement("a");
|
const link = document.createElement('a');
|
||||||
|
|
||||||
link.download = filename;
|
link.download = filename;
|
||||||
link.href = window.URL.createObjectURL(blob);
|
link.href = window.URL.createObjectURL(blob);
|
||||||
link.dataset.downloadurl = ["text/json", link.download, link.href].join(":");
|
link.dataset.downloadurl = ['text/json', link.download, link.href].join(':');
|
||||||
|
|
||||||
const evt = new MouseEvent("click", {
|
const evt = new MouseEvent('click', {
|
||||||
view: window,
|
view: window,
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
cancelable: true,
|
cancelable: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
link.dispatchEvent(evt);
|
link.dispatchEvent(evt);
|
||||||
link.remove()
|
link.remove();
|
||||||
};
|
};
|
||||||
|
@ -1,17 +1,19 @@
|
|||||||
// sort of cryptographically strong function to generate Base62 token client-side
|
// sort of cryptographically strong function to generate Base62 token client-side
|
||||||
export function genBase62Token(length){
|
export function genBase62Token(length) {
|
||||||
return window.btoa(Array.from(
|
return window
|
||||||
window.crypto.getRandomValues(
|
.btoa(
|
||||||
new Uint8Array(length * 2)))
|
Array.from(window.crypto.getRandomValues(new Uint8Array(length * 2)))
|
||||||
.map((b) => String.fromCharCode(b))
|
.map((b) => String.fromCharCode(b))
|
||||||
.join("")).replace(/[+/]/g, "")
|
.join(''),
|
||||||
.substring(0, length);
|
)
|
||||||
|
.replace(/[+/]/g, '')
|
||||||
|
.substring(0, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function tokenStrength(token) {
|
export function tokenStrength(token) {
|
||||||
const characters = token.split("").reduce(function(obj, s){
|
const characters = token.split('').reduce(function (obj, s) {
|
||||||
obj[s] = (obj[s] || 0) + 1;
|
obj[s] = (obj[s] || 0) + 1;
|
||||||
return obj;
|
return obj;
|
||||||
}, {});
|
}, {});
|
||||||
return {uniqueValues:Object.keys(characters).length,counts:Object.values(characters)}
|
return { uniqueValues: Object.keys(characters).length, counts: Object.values(characters) };
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
import { requestProvider, WeblnProvider } from "webln";
|
import { requestProvider, WeblnProvider } from 'webln';
|
||||||
|
|
||||||
export const getWebln = async (): Promise<WeblnProvider> => {
|
export const getWebln = async (): Promise<WeblnProvider> => {
|
||||||
const resultPromise = new Promise<WeblnProvider>(async (resolve, reject) => {
|
const resultPromise = new Promise<WeblnProvider>(async (resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
const webln = await requestProvider()
|
const webln = await requestProvider();
|
||||||
if (webln) {
|
if (webln) {
|
||||||
webln.enable()
|
webln.enable();
|
||||||
resolve(webln)
|
resolve(webln);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log("Coulnd't connect to Webln")
|
console.log("Coulnd't connect to Webln");
|
||||||
reject()
|
reject();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
return resultPromise
|
return resultPromise;
|
||||||
}
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user