mirror of
https://github.com/RoboSats/robosats.git
synced 2024-12-14 19:36:24 +00:00
Add functional homepage (#289)
* App as functional component * Add Main component WIP * Add Maker and Book page to new main.tsx * Add old UserGen and BottomBar to new main.tsx * Small fixes * Try out to revert depth chart * Small fixes (more)
This commit is contained in:
parent
130bd2222b
commit
04126ae0bd
16
frontend/package-lock.json
generated
16
frontend/package-lock.json
generated
@ -3235,11 +3235,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mui/utils": {
|
"node_modules/@mui/utils": {
|
||||||
"version": "5.10.3",
|
"version": "5.10.9",
|
||||||
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.10.3.tgz",
|
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.10.9.tgz",
|
||||||
"integrity": "sha512-4jXMDPfx6bpMVuheLaOpKTjpzw39ogAZLeaLj5+RJec3E37/hAZMYjURfblLfTWMMoGoqkY03mNsZaEwNobBow==",
|
"integrity": "sha512-2tdHWrq3+WCy+G6TIIaFx3cg7PorXZ71P375ExuX61od1NOAJP1mK90VxQ8N4aqnj2vmO3AQDkV4oV2Ktvt4bA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.18.9",
|
"@babel/runtime": "^7.19.0",
|
||||||
"@types/prop-types": "^15.7.5",
|
"@types/prop-types": "^15.7.5",
|
||||||
"@types/react-is": "^16.7.1 || ^17.0.0",
|
"@types/react-is": "^16.7.1 || ^17.0.0",
|
||||||
"prop-types": "^15.8.1",
|
"prop-types": "^15.8.1",
|
||||||
@ -17137,11 +17137,11 @@
|
|||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"@mui/utils": {
|
"@mui/utils": {
|
||||||
"version": "5.10.3",
|
"version": "5.10.9",
|
||||||
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.10.3.tgz",
|
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.10.9.tgz",
|
||||||
"integrity": "sha512-4jXMDPfx6bpMVuheLaOpKTjpzw39ogAZLeaLj5+RJec3E37/hAZMYjURfblLfTWMMoGoqkY03mNsZaEwNobBow==",
|
"integrity": "sha512-2tdHWrq3+WCy+G6TIIaFx3cg7PorXZ71P375ExuX61od1NOAJP1mK90VxQ8N4aqnj2vmO3AQDkV4oV2Ktvt4bA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.18.9",
|
"@babel/runtime": "^7.19.0",
|
||||||
"@types/prop-types": "^15.7.5",
|
"@types/prop-types": "^15.7.5",
|
||||||
"@types/react-is": "^16.7.1 || ^17.0.0",
|
"@types/react-is": "^16.7.1 || ^17.0.0",
|
||||||
"prop-types": "^15.8.1",
|
"prop-types": "^15.8.1",
|
||||||
|
@ -1,137 +0,0 @@
|
|||||||
import React, { Component, Suspense } from 'react';
|
|
||||||
import ReactDOM from 'react-dom/client';
|
|
||||||
import HomePage from './HomePage';
|
|
||||||
import { CssBaseline, IconButton } from '@mui/material';
|
|
||||||
import { ThemeProvider, createTheme } from '@mui/material/styles';
|
|
||||||
import UnsafeAlert from './UnsafeAlert';
|
|
||||||
import { LearnDialog } from './Dialogs';
|
|
||||||
import TorConnection from './TorConnection';
|
|
||||||
|
|
||||||
import { I18nextProvider } from 'react-i18next';
|
|
||||||
import i18n from '../i18n/Web';
|
|
||||||
|
|
||||||
// Icons
|
|
||||||
import DarkModeIcon from '@mui/icons-material/DarkMode';
|
|
||||||
import LightModeIcon from '@mui/icons-material/LightMode';
|
|
||||||
import SchoolIcon from '@mui/icons-material/School';
|
|
||||||
import { systemClient } from '../services/System';
|
|
||||||
|
|
||||||
export default class App extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
expandedSettings: false,
|
|
||||||
openLearn: false,
|
|
||||||
theme: createTheme({
|
|
||||||
palette: {
|
|
||||||
mode:
|
|
||||||
window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
||||||
? 'dark'
|
|
||||||
: 'light',
|
|
||||||
background: {
|
|
||||||
default:
|
|
||||||
window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
||||||
? '#070707'
|
|
||||||
: '#fff',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
handleThemeChange = () => {
|
|
||||||
if (this.state.theme.palette.mode === 'light') {
|
|
||||||
this.setState(({ theme }) => ({
|
|
||||||
theme: createTheme({
|
|
||||||
typography: {
|
|
||||||
fontSize: theme.typography.fontSize,
|
|
||||||
},
|
|
||||||
palette: {
|
|
||||||
mode: 'dark',
|
|
||||||
background: {
|
|
||||||
default: '#070707',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
if (this.state.theme.palette.mode === 'dark') {
|
|
||||||
this.setState(({ theme }) => ({
|
|
||||||
theme: createTheme({
|
|
||||||
typography: {
|
|
||||||
fontSize: theme.typography.fontSize,
|
|
||||||
},
|
|
||||||
palette: {
|
|
||||||
mode: 'light',
|
|
||||||
background: {
|
|
||||||
default: '#fff',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
onSettingsClick = () => {
|
|
||||||
this.setState({
|
|
||||||
expandedSettings: !this.state.expandedSettings,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onZoomClick = (direction) => {
|
|
||||||
let zoomChange;
|
|
||||||
direction === 'out' ? (zoomChange = -1) : (zoomChange = 1);
|
|
||||||
this.setState(({ theme }) => ({
|
|
||||||
theme: {
|
|
||||||
...theme,
|
|
||||||
typography: {
|
|
||||||
fontSize: this.state.theme.typography.fontSize + zoomChange,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<Suspense fallback='loading language'>
|
|
||||||
<I18nextProvider i18n={i18n}>
|
|
||||||
<ThemeProvider theme={this.state.theme}>
|
|
||||||
<CssBaseline />
|
|
||||||
<LearnDialog
|
|
||||||
open={this.state.openLearn}
|
|
||||||
onClose={() => this.setState({ openLearn: false })}
|
|
||||||
/>
|
|
||||||
<TorConnection />
|
|
||||||
<IconButton
|
|
||||||
color='inherit'
|
|
||||||
sx={{ position: 'fixed', right: '34px', color: 'text.secondary' }}
|
|
||||||
onClick={() => this.setState({ openLearn: true })}
|
|
||||||
>
|
|
||||||
<SchoolIcon />
|
|
||||||
</IconButton>
|
|
||||||
<IconButton
|
|
||||||
color='inherit'
|
|
||||||
sx={{ position: 'fixed', right: '0px', color: 'text.secondary' }}
|
|
||||||
onClick={() => this.handleThemeChange()}
|
|
||||||
>
|
|
||||||
{this.state.theme.palette.mode === 'dark' ? <LightModeIcon /> : <DarkModeIcon />}
|
|
||||||
</IconButton>
|
|
||||||
<UnsafeAlert className='unsafeAlert' />
|
|
||||||
<HomePage {...this.state} />
|
|
||||||
</ThemeProvider>
|
|
||||||
</I18nextProvider>
|
|
||||||
</Suspense>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const loadApp = () => {
|
|
||||||
if (systemClient.loading) {
|
|
||||||
setTimeout(loadApp, 200);
|
|
||||||
} else {
|
|
||||||
const root = ReactDOM.createRoot(document.getElementById('app'));
|
|
||||||
root.render(<App />);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
loadApp();
|
|
102
frontend/src/components/App.tsx
Normal file
102
frontend/src/components/App.tsx
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
import React, { Suspense, useState } from 'react';
|
||||||
|
import ReactDOM from 'react-dom/client';
|
||||||
|
import Main from './Main';
|
||||||
|
import { CssBaseline, IconButton } from '@mui/material';
|
||||||
|
import { ThemeProvider, createTheme } from '@mui/material/styles';
|
||||||
|
import UnsafeAlert from './UnsafeAlert';
|
||||||
|
import { LearnDialog } from './Dialogs';
|
||||||
|
import TorConnection from './TorConnection';
|
||||||
|
|
||||||
|
import { I18nextProvider } from 'react-i18next';
|
||||||
|
import i18n from '../i18n/Web';
|
||||||
|
|
||||||
|
// Icons
|
||||||
|
import DarkModeIcon from '@mui/icons-material/DarkMode';
|
||||||
|
import LightModeIcon from '@mui/icons-material/LightMode';
|
||||||
|
import SchoolIcon from '@mui/icons-material/School';
|
||||||
|
import { systemClient } from '../services/System';
|
||||||
|
|
||||||
|
const defaultTheme = createTheme({
|
||||||
|
palette: {
|
||||||
|
mode:
|
||||||
|
window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||||
|
? 'dark'
|
||||||
|
: 'light',
|
||||||
|
background: {
|
||||||
|
default:
|
||||||
|
window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||||
|
? '#070707'
|
||||||
|
: '#fff',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const App = (): JSX.Element => {
|
||||||
|
const [openLearn, setOpenLearn] = useState<boolean>(false);
|
||||||
|
const [theme, setTheme] = useState(defaultTheme);
|
||||||
|
|
||||||
|
const handleModeChange = function () {
|
||||||
|
if (theme.palette.mode === 'light') {
|
||||||
|
setTheme(
|
||||||
|
createTheme({
|
||||||
|
palette: {
|
||||||
|
mode: 'dark',
|
||||||
|
background: {
|
||||||
|
default: '#070707',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
} else if (theme.palette.mode === 'dark') {
|
||||||
|
setTheme(
|
||||||
|
createTheme({
|
||||||
|
palette: {
|
||||||
|
mode: 'light',
|
||||||
|
background: {
|
||||||
|
default: '#fff',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Suspense fallback='loading language'>
|
||||||
|
<I18nextProvider i18n={i18n}>
|
||||||
|
<ThemeProvider theme={theme}>
|
||||||
|
<CssBaseline />
|
||||||
|
<LearnDialog open={openLearn} onClose={() => setOpenLearn(false)} />
|
||||||
|
<TorConnection />
|
||||||
|
<IconButton
|
||||||
|
color='inherit'
|
||||||
|
sx={{ position: 'fixed', right: '34px', color: 'text.secondary' }}
|
||||||
|
onClick={() => setOpenLearn(true)}
|
||||||
|
>
|
||||||
|
<SchoolIcon />
|
||||||
|
</IconButton>
|
||||||
|
<IconButton
|
||||||
|
color='inherit'
|
||||||
|
sx={{ position: 'fixed', right: '0px', color: 'text.secondary' }}
|
||||||
|
onClick={() => handleModeChange()}
|
||||||
|
>
|
||||||
|
{theme.palette.mode === 'dark' ? <LightModeIcon /> : <DarkModeIcon />}
|
||||||
|
</IconButton>
|
||||||
|
<UnsafeAlert className='unsafeAlert' />
|
||||||
|
<Main />
|
||||||
|
</ThemeProvider>
|
||||||
|
</I18nextProvider>
|
||||||
|
</Suspense>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadApp = () => {
|
||||||
|
if (systemClient.loading) {
|
||||||
|
setTimeout(loadApp, 200);
|
||||||
|
} else {
|
||||||
|
const root = ReactDOM.createRoot(document.getElementById('app') ?? new HTMLElement());
|
||||||
|
root.render(<App />);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
loadApp();
|
@ -5,7 +5,7 @@ import { useHistory } from 'react-router-dom';
|
|||||||
import currencyDict from '../../../static/assets/currencies.json';
|
import currencyDict from '../../../static/assets/currencies.json';
|
||||||
import DepthChart from '../Charts/DepthChart';
|
import DepthChart from '../Charts/DepthChart';
|
||||||
|
|
||||||
import { Order, LimitList, Maker } from '../../models';
|
import { Book, Favorites, LimitList, Maker } from '../../models';
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
import { BarChart, FormatListBulleted } from '@mui/icons-material';
|
import { BarChart, FormatListBulleted } from '@mui/icons-material';
|
||||||
@ -13,43 +13,37 @@ import BookTable from './BookTable';
|
|||||||
import { MakerForm } from '../MakerPage';
|
import { MakerForm } from '../MakerPage';
|
||||||
|
|
||||||
interface BookPageProps {
|
interface BookPageProps {
|
||||||
bookLoading?: boolean;
|
book: Book;
|
||||||
bookRefreshing?: boolean;
|
limits: { list: LimitList; loading: boolean };
|
||||||
loadingLimits: boolean;
|
|
||||||
lastDayPremium: number;
|
|
||||||
orders: Order[];
|
|
||||||
limits: LimitList;
|
|
||||||
fetchLimits: () => void;
|
fetchLimits: () => void;
|
||||||
type: number;
|
fav: Favorites;
|
||||||
currency: number;
|
setFav: (state: Favorites) => void;
|
||||||
windowWidth: number;
|
fetchBook: () => void;
|
||||||
windowHeight: number;
|
windowSize: { width: number; height: number };
|
||||||
fetchBook: (loading: boolean, refreshing: boolean) => void;
|
lastDayPremium: number;
|
||||||
setAppState: (state: object) => void;
|
maker: Maker;
|
||||||
|
setMaker: (state: Maker) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BookPage = ({
|
const BookPage = ({
|
||||||
bookLoading = false,
|
|
||||||
bookRefreshing = false,
|
|
||||||
lastDayPremium = 0,
|
lastDayPremium = 0,
|
||||||
loadingLimits,
|
|
||||||
orders = [],
|
|
||||||
limits,
|
limits,
|
||||||
fetchLimits,
|
book = { orders: [], loading: true },
|
||||||
type,
|
|
||||||
currency,
|
|
||||||
windowWidth,
|
|
||||||
windowHeight,
|
|
||||||
setAppState,
|
|
||||||
fetchBook,
|
fetchBook,
|
||||||
|
fetchLimits,
|
||||||
|
fav,
|
||||||
|
setFav,
|
||||||
|
maker,
|
||||||
|
setMaker,
|
||||||
|
windowSize,
|
||||||
}: BookPageProps): JSX.Element => {
|
}: BookPageProps): JSX.Element => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const [view, setView] = useState<'list' | 'depth'>('list');
|
const [view, setView] = useState<'list' | 'depth'>('list');
|
||||||
const [openMaker, setOpenMaker] = useState<boolean>(false);
|
const [openMaker, setOpenMaker] = useState<boolean>(false);
|
||||||
|
|
||||||
const doubleView = windowWidth > 115;
|
const doubleView = windowSize.width > 115;
|
||||||
const width = windowWidth * 0.9;
|
const width = windowSize.width * 0.9;
|
||||||
const maxBookTableWidth = 85;
|
const maxBookTableWidth = 85;
|
||||||
const chartWidthEm = width - maxBookTableWidth;
|
const chartWidthEm = width - maxBookTableWidth;
|
||||||
|
|
||||||
@ -72,10 +66,8 @@ const BookPage = ({
|
|||||||
badSatoshisText: '',
|
badSatoshisText: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
const [maker, setMaker] = useState<Maker>(defaultMaker);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (orders.length < 1) {
|
if (book.orders.length < 1) {
|
||||||
fetchBook(true, false);
|
fetchBook(true, false);
|
||||||
} else {
|
} else {
|
||||||
fetchBook(false, true);
|
fetchBook(false, true);
|
||||||
@ -84,11 +76,11 @@ const BookPage = ({
|
|||||||
|
|
||||||
const handleCurrencyChange = function (e) {
|
const handleCurrencyChange = function (e) {
|
||||||
const currency = e.target.value;
|
const currency = e.target.value;
|
||||||
setAppState({ currency });
|
setFav({ ...fav, currency });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTypeChange = function (mouseEvent, val) {
|
const handleTypeChange = function (mouseEvent, val) {
|
||||||
setAppState({ type: val });
|
setFav({ ...fav, type: val });
|
||||||
};
|
};
|
||||||
|
|
||||||
const NoOrdersFound = function () {
|
const NoOrdersFound = function () {
|
||||||
@ -102,12 +94,14 @@ const BookPage = ({
|
|||||||
>
|
>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Typography align='center' component='h5' variant='h5'>
|
<Typography align='center' component='h5' variant='h5'>
|
||||||
{type == 0
|
{fav.type == 0
|
||||||
? t('No orders found to sell BTC for {{currencyCode}}', {
|
? t('No orders found to sell BTC for {{currencyCode}}', {
|
||||||
currencyCode: currency == 0 ? t('ANY') : currencyDict[currency.toString()],
|
currencyCode:
|
||||||
|
fav.currency == 0 ? t('ANY') : currencyDict[fav.currency.toString()],
|
||||||
})
|
})
|
||||||
: t('No orders found to buy BTC for {{currencyCode}}', {
|
: t('No orders found to buy BTC for {{currencyCode}}', {
|
||||||
currencyCode: currency == 0 ? t('ANY') : currencyDict[currency.toString()],
|
currencyCode:
|
||||||
|
fav.currency == 0 ? t('ANY') : currencyDict[fav.currency.toString()],
|
||||||
})}
|
})}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
@ -159,14 +153,11 @@ const BookPage = ({
|
|||||||
<MakerForm
|
<MakerForm
|
||||||
limits={limits}
|
limits={limits}
|
||||||
fetchLimits={fetchLimits}
|
fetchLimits={fetchLimits}
|
||||||
loadingLimits={loadingLimits}
|
|
||||||
pricingMethods={false}
|
pricingMethods={false}
|
||||||
setAppState={setAppState}
|
|
||||||
maker={maker}
|
maker={maker}
|
||||||
defaultMaker={defaultMaker}
|
|
||||||
setMaker={setMaker}
|
setMaker={setMaker}
|
||||||
type={type}
|
fav={fav}
|
||||||
currency={currency}
|
setFav={setFav}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
@ -180,20 +171,17 @@ const BookPage = ({
|
|||||||
justifyContent='center'
|
justifyContent='center'
|
||||||
spacing={1}
|
spacing={1}
|
||||||
direction='row'
|
direction='row'
|
||||||
style={{ width: `${windowWidth}em` }}
|
style={{ width: `${windowSize.width}em` }}
|
||||||
>
|
>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<BookTable
|
<BookTable
|
||||||
loading={bookLoading}
|
clickRefresh={() => fetchBook()}
|
||||||
refreshing={bookRefreshing}
|
book={book}
|
||||||
clickRefresh={() => fetchBook(false, true)}
|
fav={fav}
|
||||||
orders={orders}
|
|
||||||
type={type}
|
|
||||||
currency={currency}
|
|
||||||
maxWidth={maxBookTableWidth} // EM units
|
maxWidth={maxBookTableWidth} // EM units
|
||||||
maxHeight={windowHeight * 0.825 - 5} // EM units
|
maxHeight={windowSize.height * 0.825 - 5} // EM units
|
||||||
fullWidth={windowWidth} // EM units
|
fullWidth={windowSize.width} // EM units
|
||||||
fullHeight={windowHeight} // EM units
|
fullHeight={windowSize.height} // EM units
|
||||||
defaultFullscreen={false}
|
defaultFullscreen={false}
|
||||||
onCurrencyChange={handleCurrencyChange}
|
onCurrencyChange={handleCurrencyChange}
|
||||||
onTypeChange={handleTypeChange}
|
onTypeChange={handleTypeChange}
|
||||||
@ -202,41 +190,33 @@ const BookPage = ({
|
|||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<DepthChart
|
<DepthChart
|
||||||
orders={orders}
|
orders={book.orders}
|
||||||
lastDayPremium={lastDayPremium}
|
lastDayPremium={lastDayPremium}
|
||||||
currency={currency}
|
currency={fav.currency}
|
||||||
compact={true}
|
limits={limits.list}
|
||||||
setAppState={setAppState}
|
|
||||||
limits={limits}
|
|
||||||
maxWidth={chartWidthEm} // EM units
|
maxWidth={chartWidthEm} // EM units
|
||||||
maxHeight={windowHeight * 0.825 - 5} // EM units
|
maxHeight={windowSize.height * 0.825 - 5} // EM units
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
) : view === 'depth' ? (
|
) : view === 'depth' ? (
|
||||||
<DepthChart
|
<DepthChart
|
||||||
bookLoading={bookLoading}
|
orders={book.orders}
|
||||||
orders={orders}
|
|
||||||
lastDayPremium={lastDayPremium}
|
lastDayPremium={lastDayPremium}
|
||||||
currency={currency}
|
currency={fav.currency}
|
||||||
compact={true}
|
limits={limits.list}
|
||||||
setAppState={setAppState}
|
maxWidth={windowSize.width * 0.8} // EM units
|
||||||
limits={limits}
|
maxHeight={windowSize.height * 0.825 - 5} // EM units
|
||||||
maxWidth={windowWidth * 0.8} // EM units
|
|
||||||
maxHeight={windowHeight * 0.825 - 5} // EM units
|
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<BookTable
|
<BookTable
|
||||||
loading={bookLoading}
|
book={book}
|
||||||
refreshing={bookRefreshing}
|
clickRefresh={() => fetchBook()}
|
||||||
clickRefresh={() => fetchBook(false, true)}
|
fav={fav}
|
||||||
orders={orders}
|
maxWidth={windowSize.width * 0.97} // EM units
|
||||||
type={type}
|
maxHeight={windowSize.height * 0.825 - 5} // EM units
|
||||||
currency={currency}
|
fullWidth={windowSize.width} // EM units
|
||||||
maxWidth={windowWidth * 0.97} // EM units
|
fullHeight={windowSize.height} // EM units
|
||||||
maxHeight={windowHeight * 0.825 - 5} // EM units
|
|
||||||
fullWidth={windowWidth} // EM units
|
|
||||||
fullHeight={windowHeight} // EM units
|
|
||||||
defaultFullscreen={false}
|
defaultFullscreen={false}
|
||||||
onCurrencyChange={handleCurrencyChange}
|
onCurrencyChange={handleCurrencyChange}
|
||||||
onTypeChange={handleTypeChange}
|
onTypeChange={handleTypeChange}
|
||||||
|
@ -18,7 +18,7 @@ import {
|
|||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { DataGrid, GridPagination } from '@mui/x-data-grid';
|
import { DataGrid, GridPagination } from '@mui/x-data-grid';
|
||||||
import currencyDict from '../../../static/assets/currencies.json';
|
import currencyDict from '../../../static/assets/currencies.json';
|
||||||
import { Order } from '../../models';
|
import { Book, Favorites } from '../../models';
|
||||||
import filterOrders from '../../utils/filterOrders';
|
import filterOrders from '../../utils/filterOrders';
|
||||||
import BookControl from './BookControl';
|
import BookControl from './BookControl';
|
||||||
|
|
||||||
@ -30,15 +30,12 @@ import hexToRgb from '../../utils/hexToRgb';
|
|||||||
import statusBadgeColor from '../../utils/statusBadgeColor';
|
import statusBadgeColor from '../../utils/statusBadgeColor';
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
import { Fullscreen, FullscreenExit, Refresh, WidthFull } from '@mui/icons-material';
|
import { Fullscreen, FullscreenExit, Refresh } from '@mui/icons-material';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
loading?: boolean;
|
|
||||||
refreshing?: boolean;
|
|
||||||
clickRefresh?: () => void;
|
clickRefresh?: () => void;
|
||||||
orders: Order[];
|
book: Book;
|
||||||
type: number;
|
fav?: Favorites;
|
||||||
currency: number;
|
|
||||||
maxWidth: number;
|
maxWidth: number;
|
||||||
maxHeight: number;
|
maxHeight: number;
|
||||||
fullWidth?: number;
|
fullWidth?: number;
|
||||||
@ -46,18 +43,15 @@ interface Props {
|
|||||||
defaultFullscreen: boolean;
|
defaultFullscreen: boolean;
|
||||||
showControls?: boolean;
|
showControls?: boolean;
|
||||||
showFooter?: boolean;
|
showFooter?: boolean;
|
||||||
onCurrencyChange?: () => void;
|
onCurrencyChange?: (e: any) => void;
|
||||||
onTypeChange?: () => void;
|
onTypeChange?: (mouseEvent: any, val: number) => void;
|
||||||
noResultsOverlay?: JSX.Element;
|
noResultsOverlay?: () => JSX.Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BookTable = ({
|
const BookTable = ({
|
||||||
loading = false,
|
|
||||||
refreshing = false,
|
|
||||||
clickRefresh,
|
clickRefresh,
|
||||||
orders,
|
book,
|
||||||
type,
|
fav,
|
||||||
currency,
|
|
||||||
maxWidth,
|
maxWidth,
|
||||||
maxHeight,
|
maxHeight,
|
||||||
fullWidth,
|
fullWidth,
|
||||||
@ -666,8 +660,8 @@ const BookTable = ({
|
|||||||
return (
|
return (
|
||||||
<BookControl
|
<BookControl
|
||||||
width={width}
|
width={width}
|
||||||
type={type}
|
type={fav.type}
|
||||||
currency={currency}
|
currency={fav.currency}
|
||||||
onCurrencyChange={onCurrencyChange}
|
onCurrencyChange={onCurrencyChange}
|
||||||
onTypeChange={onTypeChange}
|
onTypeChange={onTypeChange}
|
||||||
paymentMethod={paymentMethods}
|
paymentMethod={paymentMethods}
|
||||||
@ -702,17 +696,17 @@ const BookTable = ({
|
|||||||
rows={
|
rows={
|
||||||
showControls
|
showControls
|
||||||
? filterOrders({
|
? filterOrders({
|
||||||
orders,
|
orders: book.orders,
|
||||||
baseFilter: { currency, type },
|
baseFilter: fav,
|
||||||
paymentMethods,
|
paymentMethods,
|
||||||
})
|
})
|
||||||
: orders
|
: book.orders
|
||||||
}
|
}
|
||||||
loading={loading || refreshing}
|
loading={book.loading}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
hideFooter={!showFooter}
|
hideFooter={!showFooter}
|
||||||
components={gridComponents()}
|
components={gridComponents()}
|
||||||
pageSize={loading ? 0 : pageSize}
|
pageSize={book.loading && book.orders.length == 0 ? 0 : pageSize}
|
||||||
rowsPerPageOptions={width < 22 ? [] : [0, pageSize, defaultPageSize * 2, 50, 100]}
|
rowsPerPageOptions={width < 22 ? [] : [0, pageSize, defaultPageSize * 2, 50, 100]}
|
||||||
onPageSizeChange={(newPageSize) => {
|
onPageSizeChange={(newPageSize) => {
|
||||||
setPageSize(newPageSize);
|
setPageSize(newPageSize);
|
||||||
@ -728,16 +722,20 @@ const BookTable = ({
|
|||||||
<Paper style={{ width: '100%', height: '100%', overflow: 'auto' }}>
|
<Paper style={{ width: '100%', height: '100%', overflow: 'auto' }}>
|
||||||
<DataGrid
|
<DataGrid
|
||||||
localeText={localeText}
|
localeText={localeText}
|
||||||
rows={orders.filter(
|
rows={
|
||||||
(order) =>
|
showControls
|
||||||
(order.type == type || type == null) &&
|
? filterOrders({
|
||||||
(order.currency == currency || currency == 0),
|
orders: book.orders,
|
||||||
)}
|
baseFilter: fav,
|
||||||
loading={loading || refreshing}
|
paymentMethods,
|
||||||
|
})
|
||||||
|
: book.orders
|
||||||
|
}
|
||||||
|
loading={book.loading}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
hideFooter={!showFooter}
|
hideFooter={!showFooter}
|
||||||
components={gridComponents()}
|
components={gridComponents()}
|
||||||
pageSize={loading ? 0 : pageSize}
|
pageSize={book.loading && book.orders.length == 0 ? 0 : pageSize}
|
||||||
rowsPerPageOptions={[0, pageSize, defaultPageSize * 2, 50, 100]}
|
rowsPerPageOptions={[0, pageSize, defaultPageSize * 2, 50, 100]}
|
||||||
onPageSizeChange={(newPageSize) => {
|
onPageSizeChange={(newPageSize) => {
|
||||||
setPageSize(newPageSize);
|
setPageSize(newPageSize);
|
||||||
|
@ -4,7 +4,6 @@ import {
|
|||||||
Badge,
|
Badge,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
ListItemAvatar,
|
ListItemAvatar,
|
||||||
Avatar,
|
|
||||||
Paper,
|
Paper,
|
||||||
Grid,
|
Grid,
|
||||||
IconButton,
|
IconButton,
|
||||||
@ -42,31 +41,16 @@ import {
|
|||||||
UpdateClientDialog,
|
UpdateClientDialog,
|
||||||
} from './Dialogs';
|
} from './Dialogs';
|
||||||
|
|
||||||
import checkVer from '../utils/checkVer';
|
|
||||||
|
|
||||||
class BottomBar extends Component {
|
class BottomBar extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
|
profileShown: false,
|
||||||
openStatsForNerds: false,
|
openStatsForNerds: false,
|
||||||
openCommuniy: false,
|
openCommunity: false,
|
||||||
openExchangeSummary: false,
|
openExchangeSummary: false,
|
||||||
openClaimRewards: false,
|
openClaimRewards: false,
|
||||||
openUpdateClient: false,
|
|
||||||
num_public_buy_orders: 0,
|
|
||||||
num_public_sell_orders: 0,
|
|
||||||
book_liquidity: 0,
|
|
||||||
active_robots_today: 0,
|
|
||||||
maker_fee: 0,
|
|
||||||
taker_fee: 0,
|
|
||||||
last_day_nonkyc_btc_premium: 0,
|
|
||||||
last_day_volume: 0,
|
|
||||||
lifetime_volume: 0,
|
|
||||||
robosats_running_commit_hash: '000000000000000',
|
|
||||||
openProfile: false,
|
openProfile: false,
|
||||||
profileShown: false,
|
|
||||||
alternative_site: 'robosats...',
|
|
||||||
node_id: '00000000',
|
|
||||||
showRewards: false,
|
showRewards: false,
|
||||||
rewardInvoice: null,
|
rewardInvoice: null,
|
||||||
badInvoice: false,
|
badInvoice: false,
|
||||||
@ -75,36 +59,6 @@ class BottomBar extends Component {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this.getInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
getInfo() {
|
|
||||||
this.setState(null);
|
|
||||||
apiClient.get('/api/info/').then((data) => {
|
|
||||||
const versionInfo = checkVer(data.version.major, data.version.minor, data.version.patch);
|
|
||||||
this.setState({
|
|
||||||
...data,
|
|
||||||
openUpdateClient: versionInfo.updateAvailable,
|
|
||||||
coordinatorVersion: versionInfo.coordinatorVersion,
|
|
||||||
clientVersion: versionInfo.clientVersion,
|
|
||||||
});
|
|
||||||
this.props.setAppState({
|
|
||||||
nickname: data.nickname,
|
|
||||||
loading: false,
|
|
||||||
activeOrderId: data.active_order_id ? data.active_order_id : null,
|
|
||||||
lastOrderId: data.last_order_id ? data.last_order_id : null,
|
|
||||||
referralCode: data.referral_code,
|
|
||||||
tgEnabled: data.tg_enabled,
|
|
||||||
tgBotName: data.tg_bot_name,
|
|
||||||
tgToken: data.tg_token,
|
|
||||||
earnedRewards: data.earned_rewards,
|
|
||||||
lastDayPremium: data.last_day_nonkyc_btc_premium,
|
|
||||||
stealthInvoices: data.wants_stealth,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleClickOpenStatsForNerds = () => {
|
handleClickOpenStatsForNerds = () => {
|
||||||
this.setState({ openStatsForNerds: true });
|
this.setState({ openStatsForNerds: true });
|
||||||
};
|
};
|
||||||
@ -114,15 +68,14 @@ class BottomBar extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
handleClickOpenCommunity = () => {
|
handleClickOpenCommunity = () => {
|
||||||
this.setState({ openCommuniy: true });
|
this.setState({ openCommunity: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
handleClickCloseCommunity = () => {
|
handleClickCloseCommunity = () => {
|
||||||
this.setState({ openCommuniy: false });
|
this.setState({ openCommunity: false });
|
||||||
};
|
};
|
||||||
|
|
||||||
handleClickOpenProfile = () => {
|
handleClickOpenProfile = () => {
|
||||||
this.getInfo();
|
|
||||||
this.setState({ openProfile: true, profileShown: true });
|
this.setState({ openProfile: true, profileShown: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -130,35 +83,44 @@ class BottomBar extends Component {
|
|||||||
this.setState({ openProfile: false });
|
this.setState({ openProfile: false });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handleClickOpenExchangeSummary = () => {
|
||||||
|
this.setState({ openExchangeSummary: true });
|
||||||
|
};
|
||||||
|
|
||||||
|
handleClickCloseExchangeSummary = () => {
|
||||||
|
this.setState({ openExchangeSummary: false });
|
||||||
|
};
|
||||||
|
|
||||||
handleSubmitInvoiceClicked = (e, rewardInvoice) => {
|
handleSubmitInvoiceClicked = (e, rewardInvoice) => {
|
||||||
this.setState({
|
this.setState({ badInvoice: false, showRewardsSpinner: true });
|
||||||
badInvoice: false,
|
|
||||||
showRewardsSpinner: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
apiClient
|
apiClient
|
||||||
.post('/api/reward/', {
|
.post('/api/reward/', {
|
||||||
invoice: rewardInvoice,
|
invoice: rewardInvoice,
|
||||||
})
|
})
|
||||||
.then(
|
.then((data) => {
|
||||||
(data) =>
|
this.setState({ badInvoice: data.bad_invoice, showRewardsSpinner: false });
|
||||||
this.setState({
|
this.props.setInfo({
|
||||||
|
...this.props.info,
|
||||||
badInvoice: data.bad_invoice,
|
badInvoice: data.bad_invoice,
|
||||||
openClaimRewards: !data.successful_withdrawal,
|
openClaimRewards: !data.successful_withdrawal,
|
||||||
withdrawn: !!data.successful_withdrawal,
|
withdrawn: !!data.successful_withdrawal,
|
||||||
showRewardsSpinner: false,
|
showRewardsSpinner: false,
|
||||||
}) &
|
});
|
||||||
this.props.setAppState({
|
this.props.setRobot({
|
||||||
earnedRewards: data.successful_withdrawal ? 0 : this.props.earnedRewards,
|
...this.props.robot,
|
||||||
}),
|
earnedRewards: data.successful_withdrawal ? 0 : this.props.robot.earnedRewards,
|
||||||
);
|
});
|
||||||
|
});
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
};
|
};
|
||||||
|
|
||||||
handleSetStealthInvoice = (wantsStealth) => {
|
handleSetStealthInvoice = (wantsStealth) => {
|
||||||
apiClient
|
apiClient
|
||||||
.put('/api/stealth/', { wantsStealth })
|
.put('/api/stealth/', { wantsStealth })
|
||||||
.then((data) => this.props.setAppState({ stealthInvoices: data?.wantsStealth }));
|
.then((data) =>
|
||||||
|
this.props.setRobot({ ...this.props.robot, stealthInvoices: data?.wantsStealth }),
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
getHost() {
|
getHost() {
|
||||||
@ -171,19 +133,21 @@ class BottomBar extends Component {
|
|||||||
|
|
||||||
showProfileButton = () => {
|
showProfileButton = () => {
|
||||||
return (
|
return (
|
||||||
this.props.avatarLoaded &&
|
this.props.robot.avatarLoaded &&
|
||||||
(this.props.token ? systemClient.getCookie('robot_token') === this.props.token : true) &&
|
(this.props.robot.token
|
||||||
|
? systemClient.getCookie('robot_token') === this.props.robot.token
|
||||||
|
: true) &&
|
||||||
systemClient.getCookie('sessionid')
|
systemClient.getCookie('sessionid')
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
bottomBarDesktop = () => {
|
bottomBarDesktop = () => {
|
||||||
const { t } = this.props;
|
const { t } = this.props;
|
||||||
const hasRewards = this.props.earnedRewards > 0;
|
const hasRewards = this.props.robot.earnedRewards > 0;
|
||||||
const hasOrder = !!(
|
const hasOrder = !!(
|
||||||
(this.props.activeOrderId > 0) &
|
(this.props.robot.activeOrderId > 0) &
|
||||||
!this.state.profileShown &
|
!this.state.profileShown &
|
||||||
this.props.avatarLoaded
|
this.props.robot.avatarLoaded
|
||||||
);
|
);
|
||||||
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
|
||||||
@ -192,7 +156,10 @@ class BottomBar extends Component {
|
|||||||
secondaryTypographyProps: { fontSize: (fontSize * 12) / 14 },
|
secondaryTypographyProps: { fontSize: (fontSize * 12) / 14 },
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<Paper elevation={6} style={{ height: '2.85em', width: '100%' }}>
|
<Paper
|
||||||
|
elevation={6}
|
||||||
|
style={{ height: '2.5em', width: `${(this.props.windowSize.width / 16) * 14}em` }}
|
||||||
|
>
|
||||||
<Grid container>
|
<Grid container>
|
||||||
<Grid item xs={1.9}>
|
<Grid item xs={1.9}>
|
||||||
<div style={{ display: this.showProfileButton() ? '' : 'none' }}>
|
<div style={{ display: this.showProfileButton() ? '' : 'none' }}>
|
||||||
@ -208,16 +175,18 @@ class BottomBar extends Component {
|
|||||||
<RobotAvatar
|
<RobotAvatar
|
||||||
style={{ marginTop: -13 }}
|
style={{ marginTop: -13 }}
|
||||||
statusColor={
|
statusColor={
|
||||||
(this.props.activeOrderId > 0) & !this.props.profileShown
|
(this.props.robot.activeOrderId > 0) & !this.state.profileShown
|
||||||
? 'primary'
|
? 'primary'
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
nickname={this.props.nickname}
|
nickname={this.props.robot.nickname}
|
||||||
onLoad={() => this.props.setAppState({ avatarLoaded: true })}
|
onLoad={() =>
|
||||||
|
this.props.setRobot({ ...this.props.robot, avatarLoaded: true })
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</ListItemAvatar>
|
</ListItemAvatar>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<ListItemText primary={this.props.nickname} />
|
<ListItemText primary={this.props.robot.nickname} />
|
||||||
</ListItemButton>
|
</ListItemButton>
|
||||||
</div>
|
</div>
|
||||||
</Grid>
|
</Grid>
|
||||||
@ -228,10 +197,6 @@ class BottomBar extends Component {
|
|||||||
<IconButton
|
<IconButton
|
||||||
disabled={!this.showProfileButton()}
|
disabled={!this.showProfileButton()}
|
||||||
color='primary'
|
color='primary'
|
||||||
onClick={() =>
|
|
||||||
this.props.setAppState({ buyChecked: false, sellChecked: true, type: 0 }) &
|
|
||||||
this.getInfo()
|
|
||||||
}
|
|
||||||
to={`/book/`}
|
to={`/book/`}
|
||||||
component={LinkRouter}
|
component={LinkRouter}
|
||||||
>
|
>
|
||||||
@ -240,7 +205,7 @@ class BottomBar extends Component {
|
|||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
{...typographyProps}
|
{...typographyProps}
|
||||||
primary={this.state.num_public_buy_orders}
|
primary={this.props.info.num_public_buy_orders}
|
||||||
secondary={t('Public Buy Orders')}
|
secondary={t('Public Buy Orders')}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
@ -252,10 +217,6 @@ class BottomBar extends Component {
|
|||||||
<IconButton
|
<IconButton
|
||||||
disabled={!this.showProfileButton()}
|
disabled={!this.showProfileButton()}
|
||||||
color='primary'
|
color='primary'
|
||||||
onClick={() =>
|
|
||||||
this.props.setAppState({ buyChecked: true, sellChecked: false, type: 1 }) &
|
|
||||||
this.getInfo()
|
|
||||||
}
|
|
||||||
to={`/book/`}
|
to={`/book/`}
|
||||||
component={LinkRouter}
|
component={LinkRouter}
|
||||||
>
|
>
|
||||||
@ -264,7 +225,7 @@ class BottomBar extends Component {
|
|||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
{...typographyProps}
|
{...typographyProps}
|
||||||
primary={this.state.num_public_sell_orders}
|
primary={this.props.info.num_public_sell_orders}
|
||||||
secondary={t('Public Sell Orders')}
|
secondary={t('Public Sell Orders')}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
@ -276,7 +237,6 @@ class BottomBar extends Component {
|
|||||||
<IconButton
|
<IconButton
|
||||||
disabled={!this.showProfileButton()}
|
disabled={!this.showProfileButton()}
|
||||||
color='primary'
|
color='primary'
|
||||||
onClick={() => this.getInfo()}
|
|
||||||
to={`/`}
|
to={`/`}
|
||||||
component={LinkRouter}
|
component={LinkRouter}
|
||||||
>
|
>
|
||||||
@ -285,7 +245,7 @@ class BottomBar extends Component {
|
|||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
{...typographyProps}
|
{...typographyProps}
|
||||||
primary={this.state.active_robots_today}
|
primary={this.props.info.active_robots_today}
|
||||||
secondary={t('Today Active Robots')}
|
secondary={t('Today Active Robots')}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
@ -300,7 +260,7 @@ class BottomBar extends Component {
|
|||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
{...typographyProps}
|
{...typographyProps}
|
||||||
primary={this.state.last_day_nonkyc_btc_premium + '%'}
|
primary={this.props.info.last_day_nonkyc_btc_premium + '%'}
|
||||||
secondary={t('24h Avg Premium')}
|
secondary={t('24h Avg Premium')}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
@ -315,7 +275,7 @@ class BottomBar extends Component {
|
|||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
{...typographyProps}
|
{...typographyProps}
|
||||||
primary={(this.state.maker_fee + this.state.taker_fee) * 100}
|
primary={(this.props.info.maker_fee + this.props.info.taker_fee) * 100}
|
||||||
secondary={t('Trade Fee')}
|
secondary={t('Trade Fee')}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
@ -470,28 +430,19 @@ class BottomBar extends Component {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
handleClickOpenExchangeSummary = () => {
|
|
||||||
// avoid calling getInfo while sessionid not yet set. Temporary fix.
|
|
||||||
if (systemClient.getCookie('sessionid')) {
|
|
||||||
this.getInfo();
|
|
||||||
}
|
|
||||||
this.setState({ openExchangeSummary: true });
|
|
||||||
};
|
|
||||||
|
|
||||||
handleClickCloseExchangeSummary = () => {
|
|
||||||
this.setState({ openExchangeSummary: false });
|
|
||||||
};
|
|
||||||
|
|
||||||
bottomBarPhone = () => {
|
bottomBarPhone = () => {
|
||||||
const { t } = this.props;
|
const { t } = this.props;
|
||||||
const hasRewards = this.props.earnedRewards > 0;
|
const hasRewards = this.props.robot.earnedRewards > 0;
|
||||||
const hasOrder = !!(
|
const hasOrder = !!(
|
||||||
(this.state.active_order_id > 0) &
|
(this.props.info.active_order_id > 0) &
|
||||||
!this.state.profileShown &
|
!this.state.profileShown &
|
||||||
this.props.avatarLoaded
|
this.props.robot.avatarLoaded
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<Paper elevation={6} style={{ height: '2.85em', width: '100%' }}>
|
<Paper
|
||||||
|
elevation={6}
|
||||||
|
style={{ height: '2.85em', width: `${(this.props.windowSize.width / 16) * 14}em` }}
|
||||||
|
>
|
||||||
<Grid container>
|
<Grid container>
|
||||||
<Grid item xs={1.6}>
|
<Grid item xs={1.6}>
|
||||||
<div style={{ display: this.showProfileButton() ? '' : 'none' }}>
|
<div style={{ display: this.showProfileButton() ? '' : 'none' }}>
|
||||||
@ -510,12 +461,12 @@ class BottomBar extends Component {
|
|||||||
style={{ width: 55, height: 55 }}
|
style={{ width: 55, height: 55 }}
|
||||||
avatarClass='phoneFlippedSmallAvatar'
|
avatarClass='phoneFlippedSmallAvatar'
|
||||||
statusColor={
|
statusColor={
|
||||||
(this.props.activeOrderId > 0) & !this.props.profileShown
|
(this.props.activeOrderId > 0) & !this.state.profileShown
|
||||||
? 'primary'
|
? 'primary'
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
nickname={this.props.nickname}
|
nickname={this.props.robot.nickname}
|
||||||
onLoad={() => this.props.setAppState({ avatarLoaded: true })}
|
onLoad={() => this.props.setRobot({ ...this.props.robot, avatarLoaded: true })}
|
||||||
/>
|
/>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@ -527,14 +478,10 @@ class BottomBar extends Component {
|
|||||||
<IconButton
|
<IconButton
|
||||||
disabled={!this.showProfileButton()}
|
disabled={!this.showProfileButton()}
|
||||||
color='primary'
|
color='primary'
|
||||||
onClick={() =>
|
|
||||||
this.props.setAppState({ buyChecked: false, sellChecked: true, type: 0 }) &
|
|
||||||
this.getInfo()
|
|
||||||
}
|
|
||||||
to={`/book/`}
|
to={`/book/`}
|
||||||
component={LinkRouter}
|
component={LinkRouter}
|
||||||
>
|
>
|
||||||
<Badge badgeContent={this.state.num_public_buy_orders} color='action'>
|
<Badge badgeContent={this.props.info.num_public_buy_orders} color='action'>
|
||||||
<InventoryIcon />
|
<InventoryIcon />
|
||||||
</Badge>
|
</Badge>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
@ -546,14 +493,10 @@ class BottomBar extends Component {
|
|||||||
<IconButton
|
<IconButton
|
||||||
disabled={!this.showProfileButton()}
|
disabled={!this.showProfileButton()}
|
||||||
color='primary'
|
color='primary'
|
||||||
onClick={() =>
|
|
||||||
this.props.setAppState({ buyChecked: true, sellChecked: false, type: 1 }) &
|
|
||||||
this.getInfo()
|
|
||||||
}
|
|
||||||
to={`/book/`}
|
to={`/book/`}
|
||||||
component={LinkRouter}
|
component={LinkRouter}
|
||||||
>
|
>
|
||||||
<Badge badgeContent={this.state.num_public_sell_orders} color='action'>
|
<Badge badgeContent={this.props.info.num_public_sell_orders} color='action'>
|
||||||
<SellIcon />
|
<SellIcon />
|
||||||
</Badge>
|
</Badge>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
@ -565,11 +508,11 @@ class BottomBar extends Component {
|
|||||||
<IconButton
|
<IconButton
|
||||||
disabled={!this.showProfileButton()}
|
disabled={!this.showProfileButton()}
|
||||||
color='primary'
|
color='primary'
|
||||||
onClick={() => this.getInfo()}
|
onClick={() => this.props.fetchInfo()}
|
||||||
to={`/`}
|
to={`/`}
|
||||||
component={LinkRouter}
|
component={LinkRouter}
|
||||||
>
|
>
|
||||||
<Badge badgeContent={this.state.active_robots_today} color='action'>
|
<Badge badgeContent={this.props.info.active_robots_today} color='action'>
|
||||||
<SmartToyIcon />
|
<SmartToyIcon />
|
||||||
</Badge>
|
</Badge>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
@ -579,7 +522,10 @@ class BottomBar extends Component {
|
|||||||
<Grid item xs={1.8} align='center'>
|
<Grid item xs={1.8} align='center'>
|
||||||
<Tooltip enterTouchDelay={300} title={t('24h non-KYC bitcoin premium')}>
|
<Tooltip enterTouchDelay={300} title={t('24h non-KYC bitcoin premium')}>
|
||||||
<IconButton color='primary' onClick={this.handleClickOpenExchangeSummary}>
|
<IconButton color='primary' onClick={this.handleClickOpenExchangeSummary}>
|
||||||
<Badge badgeContent={this.state.last_day_nonkyc_btc_premium + '%'} color='action'>
|
<Badge
|
||||||
|
badgeContent={this.props.info.last_day_nonkyc_btc_premium + '%'}
|
||||||
|
color='action'
|
||||||
|
>
|
||||||
<PriceChangeIcon />
|
<PriceChangeIcon />
|
||||||
</Badge>
|
</Badge>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
@ -622,65 +568,67 @@ class BottomBar extends Component {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<CommunityDialog
|
<CommunityDialog
|
||||||
isOpen={this.state.openCommuniy}
|
open={this.state.openCommunity}
|
||||||
handleClickCloseCommunity={this.handleClickCloseCommunity}
|
handleClickCloseCommunity={this.handleClickCloseCommunity}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<UpdateClientDialog
|
<UpdateClientDialog
|
||||||
open={this.state.openUpdateClient}
|
open={this.state.openUpdateClient}
|
||||||
coordinatorVersion={this.state.coordinatorVersion}
|
coordinatorVersion={this.props.info.coordinatorVersion}
|
||||||
clientVersion={this.state.clientVersion}
|
clientVersion={this.props.info.clientVersion}
|
||||||
handleClickClose={() => this.setState({ openUpdateClient: false })}
|
handleClickClose={() =>
|
||||||
|
this.props.setInfo({ ...this.props.info, openUpdateClient: false })
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ExchangeSummaryDialog
|
<ExchangeSummaryDialog
|
||||||
isOpen={this.state.openExchangeSummary}
|
open={this.state.openExchangeSummary}
|
||||||
handleClickCloseExchangeSummary={this.handleClickCloseExchangeSummary}
|
handleClickCloseExchangeSummary={this.handleClickCloseExchangeSummary}
|
||||||
numPublicBuyOrders={this.state.num_public_buy_orders}
|
numPublicBuyOrders={this.props.info.num_public_buy_orders}
|
||||||
numPublicSellOrders={this.state.num_public_sell_orders}
|
numPublicSellOrders={this.props.info.num_public_sell_orders}
|
||||||
bookLiquidity={this.state.book_liquidity}
|
bookLiquidity={this.props.info.book_liquidity}
|
||||||
activeRobotsToday={this.state.active_robots_today}
|
activeRobotsToday={this.props.info.active_robots_today}
|
||||||
lastDayNonkycBtcPremium={this.state.last_day_nonkyc_btc_premium}
|
lastDayNonkycBtcPremium={this.props.info.last_day_nonkyc_btc_premium}
|
||||||
makerFee={this.state.maker_fee}
|
makerFee={this.props.info.maker_fee}
|
||||||
takerFee={this.state.taker_fee}
|
takerFee={this.props.info.taker_fee}
|
||||||
swapFeeRate={this.state.current_swap_fee_rate}
|
swapFeeRate={this.props.info.current_swap_fee_rate}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ProfileDialog
|
<ProfileDialog
|
||||||
isOpen={this.state.openProfile}
|
open={this.state.openProfile}
|
||||||
handleClickCloseProfile={this.handleClickCloseProfile}
|
handleClickCloseProfile={this.handleClickCloseProfile}
|
||||||
nickname={this.props.nickname}
|
nickname={this.props.robot.nickname}
|
||||||
activeOrderId={this.props.activeOrderId}
|
activeOrderId={this.props.robot.activeOrderId}
|
||||||
lastOrderId={this.props.lastOrderId}
|
lastOrderId={this.props.robotlastOrderId}
|
||||||
referralCode={this.props.referralCode}
|
referralCode={this.props.robot.referralCode}
|
||||||
tgEnabled={this.props.tgEnabled}
|
tgEnabled={this.props.robot.tgEnabled}
|
||||||
tgBotName={this.props.tgBotName}
|
tgBotName={this.props.robot.tgBotName}
|
||||||
tgToken={this.props.tgToken}
|
tgToken={this.props.robot.tgToken}
|
||||||
handleSubmitInvoiceClicked={this.handleSubmitInvoiceClicked}
|
handleSubmitInvoiceClicked={this.handleSubmitInvoiceClicked}
|
||||||
host={this.getHost()}
|
host={this.getHost()}
|
||||||
showRewardsSpinner={this.state.showRewardsSpinner}
|
showRewardsSpinner={this.state.showRewardsSpinner}
|
||||||
withdrawn={this.state.withdrawn}
|
withdrawn={this.props.info.withdrawn}
|
||||||
badInvoice={this.state.badInvoice}
|
badInvoice={this.props.info.badInvoice}
|
||||||
earnedRewards={this.props.earnedRewards}
|
earnedRewards={this.props.robot.earnedRewards}
|
||||||
setAppState={this.props.setAppState}
|
updateRobot={(newParam) => this.props.setRobot({ ...robot, ...newParam })}
|
||||||
stealthInvoices={this.props.stealthInvoices}
|
stealthInvoices={this.props.robot.stealthInvoices}
|
||||||
handleSetStealthInvoice={this.handleSetStealthInvoice}
|
handleSetStealthInvoice={this.handleSetStealthInvoice}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<StatsDialog
|
<StatsDialog
|
||||||
isOpen={this.state.openStatsForNerds}
|
open={this.state.openStatsForNerds}
|
||||||
handleClickCloseStatsForNerds={this.handleClickCloseStatsForNerds}
|
handleClickCloseStatsForNerds={this.handleClickCloseStatsForNerds}
|
||||||
coordinatorVersion={this.state.coordinatorVersion}
|
coordinatorVersion={this.props.info.coordinatorVersion}
|
||||||
clientVersion={this.state.clientVersion}
|
clientVersion={this.props.info.clientVersion}
|
||||||
lndVersion={this.state.lnd_version}
|
lndVersion={this.props.info.lnd_version}
|
||||||
network={this.state.network}
|
network={this.props.info.network}
|
||||||
nodeAlias={this.state.node_alias}
|
nodeAlias={this.props.info.node_alias}
|
||||||
nodeId={this.state.node_id}
|
nodeId={this.props.info.node_id}
|
||||||
alternativeName={this.state.alternative_name}
|
alternativeName={this.props.info.alternative_name}
|
||||||
alternativeSite={this.state.alternative_site}
|
alternativeSite={this.props.info.alternative_site}
|
||||||
commitHash={this.state.robosats_running_commit_hash}
|
commitHash={this.props.info.robosats_running_commit_hash}
|
||||||
lastDayVolume={this.state.last_day_volume}
|
lastDayVolume={this.props.info.last_day_volume}
|
||||||
lifetimeVolume={this.state.lifetime_volume}
|
lifetimeVolume={this.props.info.lifetime_volume}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<MediaQuery minWidth={1200}>{this.bottomBarDesktop()}</MediaQuery>
|
<MediaQuery minWidth={1200}>{this.bottomBarDesktop()}</MediaQuery>
|
||||||
|
@ -28,14 +28,12 @@ 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';
|
||||||
import { apiClient } from '../../../services/api/index';
|
|
||||||
import statusBadgeColor from '../../../utils/statusBadgeColor';
|
import statusBadgeColor from '../../../utils/statusBadgeColor';
|
||||||
|
|
||||||
interface DepthChartProps {
|
interface DepthChartProps {
|
||||||
orders: Order[];
|
orders: Order[];
|
||||||
lastDayPremium: number | undefined;
|
lastDayPremium: number | undefined;
|
||||||
currency: number;
|
currency: number;
|
||||||
setAppState: (state: object) => void;
|
|
||||||
limits: LimitList;
|
limits: LimitList;
|
||||||
maxWidth: number;
|
maxWidth: number;
|
||||||
maxHeight: number;
|
maxHeight: number;
|
||||||
@ -45,7 +43,6 @@ const DepthChart: React.FC<DepthChartProps> = ({
|
|||||||
orders,
|
orders,
|
||||||
lastDayPremium,
|
lastDayPremium,
|
||||||
currency,
|
currency,
|
||||||
setAppState,
|
|
||||||
limits,
|
limits,
|
||||||
maxWidth,
|
maxWidth,
|
||||||
maxHeight,
|
maxHeight,
|
||||||
@ -64,14 +61,6 @@ const DepthChart: React.FC<DepthChartProps> = ({
|
|||||||
const height = maxHeight < 20 ? 20 : maxHeight;
|
const height = maxHeight < 20 ? 20 : maxHeight;
|
||||||
const width = maxWidth < 20 ? 20 : maxWidth > 72.8 ? 72.8 : maxWidth;
|
const width = maxWidth < 20 ? 20 : maxWidth > 72.8 ? 72.8 : maxWidth;
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (Object.keys(limits).length === 0) {
|
|
||||||
apiClient.get('/api/limits/').then((data) => {
|
|
||||||
setAppState({ limits: data });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setCurrencyCode(currency === 0 ? 1 : currency);
|
setCurrencyCode(currency === 0 ? 1 : currency);
|
||||||
}, [currency]);
|
}, [currency]);
|
||||||
|
@ -12,13 +12,13 @@ export const getNivoScheme: (theme: MuiTheme) => NivoTheme = (theme) => {
|
|||||||
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)',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -36,13 +36,13 @@ export const getNivoScheme: (theme: MuiTheme) => NivoTheme = (theme) => {
|
|||||||
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)',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -20,11 +20,11 @@ import RedditIcon from '@mui/icons-material/Reddit';
|
|||||||
import Flags from 'country-flag-icons/react/3x2';
|
import Flags from 'country-flag-icons/react/3x2';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isOpen: boolean;
|
open: boolean;
|
||||||
handleClickCloseCommunity: () => void;
|
handleClickCloseCommunity: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CommunityDialog = ({ isOpen, handleClickCloseCommunity }: Props): JSX.Element => {
|
const CommunityDialog = ({ open = false, handleClickCloseCommunity }: Props): JSX.Element => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const flagProps = {
|
const flagProps = {
|
||||||
@ -38,7 +38,7 @@ const CommunityDialog = ({ isOpen, handleClickCloseCommunity }: Props): JSX.Elem
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
open={isOpen}
|
open={open}
|
||||||
onClose={handleClickCloseCommunity}
|
onClose={handleClickCloseCommunity}
|
||||||
aria-labelledby='community-dialog-title'
|
aria-labelledby='community-dialog-title'
|
||||||
aria-describedby='community-description'
|
aria-describedby='community-description'
|
||||||
|
@ -24,7 +24,7 @@ import LinkIcon from '@mui/icons-material/Link';
|
|||||||
import { pn } from '../../utils/prettyNumbers';
|
import { pn } from '../../utils/prettyNumbers';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isOpen: boolean;
|
open: boolean;
|
||||||
handleClickCloseExchangeSummary: () => void;
|
handleClickCloseExchangeSummary: () => void;
|
||||||
numPublicBuyOrders: number;
|
numPublicBuyOrders: number;
|
||||||
numPublicSellOrders: number;
|
numPublicSellOrders: number;
|
||||||
@ -37,7 +37,7 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ExchangeSummaryDialog = ({
|
const ExchangeSummaryDialog = ({
|
||||||
isOpen,
|
open = false,
|
||||||
handleClickCloseExchangeSummary,
|
handleClickCloseExchangeSummary,
|
||||||
numPublicBuyOrders,
|
numPublicBuyOrders,
|
||||||
numPublicSellOrders,
|
numPublicSellOrders,
|
||||||
@ -55,7 +55,7 @@ const ExchangeSummaryDialog = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
open={isOpen}
|
open={open}
|
||||||
onClose={handleClickCloseExchangeSummary}
|
onClose={handleClickCloseExchangeSummary}
|
||||||
aria-labelledby='exchange-summary-title'
|
aria-labelledby='exchange-summary-title'
|
||||||
aria-describedby='exchange-summary-description'
|
aria-describedby='exchange-summary-description'
|
||||||
|
@ -41,7 +41,7 @@ import { getWebln } from '../../utils/webln';
|
|||||||
import RobotAvatar from '../Robots/RobotAvatar';
|
import RobotAvatar from '../Robots/RobotAvatar';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isOpen: boolean;
|
open: boolean;
|
||||||
handleClickCloseProfile: () => void;
|
handleClickCloseProfile: () => void;
|
||||||
nickname: string;
|
nickname: string;
|
||||||
activeOrderId: string | number;
|
activeOrderId: string | number;
|
||||||
@ -57,12 +57,12 @@ interface Props {
|
|||||||
badInvoice: boolean | string;
|
badInvoice: boolean | string;
|
||||||
earnedRewards: number;
|
earnedRewards: number;
|
||||||
stealthInvoices: boolean;
|
stealthInvoices: boolean;
|
||||||
handleSetStealthInvoice: (stealth: boolean) => void;
|
handleSetStealthInvoice: (wantsStealth: boolean) => void;
|
||||||
setAppState: (state: any) => void; // TODO: move to a ContextProvider
|
updateRobot: (state: any) => void; // TODO: move to a ContextProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProfileDialog = ({
|
const ProfileDialog = ({
|
||||||
isOpen,
|
open = false,
|
||||||
handleClickCloseProfile,
|
handleClickCloseProfile,
|
||||||
nickname,
|
nickname,
|
||||||
activeOrderId,
|
activeOrderId,
|
||||||
@ -77,7 +77,7 @@ const ProfileDialog = ({
|
|||||||
withdrawn,
|
withdrawn,
|
||||||
badInvoice,
|
badInvoice,
|
||||||
earnedRewards,
|
earnedRewards,
|
||||||
setAppState,
|
updateRobot,
|
||||||
stealthInvoices,
|
stealthInvoices,
|
||||||
handleSetStealthInvoice,
|
handleSetStealthInvoice,
|
||||||
}: Props): JSX.Element => {
|
}: Props): JSX.Element => {
|
||||||
@ -101,7 +101,7 @@ const ProfileDialog = ({
|
|||||||
|
|
||||||
if (robotToken) {
|
if (robotToken) {
|
||||||
systemClient.copyToClipboard(robotToken);
|
systemClient.copyToClipboard(robotToken);
|
||||||
setAppState({ copiedToken: true });
|
updateRobot({ copiedToken: true });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ const ProfileDialog = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
open={isOpen}
|
open={open}
|
||||||
onClose={handleClickCloseProfile}
|
onClose={handleClickCloseProfile}
|
||||||
aria-labelledby='profile-title'
|
aria-labelledby='profile-title'
|
||||||
aria-describedby='profile-description'
|
aria-describedby='profile-description'
|
||||||
|
@ -26,7 +26,7 @@ import { AmbossIcon, BitcoinSignIcon, RoboSatsNoTextIcon } from '../Icons';
|
|||||||
import { pn } from '../../utils/prettyNumbers';
|
import { pn } from '../../utils/prettyNumbers';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isOpen: boolean;
|
open: boolean;
|
||||||
handleClickCloseStatsForNerds: () => void;
|
handleClickCloseStatsForNerds: () => void;
|
||||||
lndVersion: string;
|
lndVersion: string;
|
||||||
coordinatorVersion: string;
|
coordinatorVersion: string;
|
||||||
@ -42,7 +42,7 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const StatsDialog = ({
|
const StatsDialog = ({
|
||||||
isOpen,
|
open = false,
|
||||||
handleClickCloseStatsForNerds,
|
handleClickCloseStatsForNerds,
|
||||||
lndVersion,
|
lndVersion,
|
||||||
coordinatorVersion,
|
coordinatorVersion,
|
||||||
@ -60,7 +60,7 @@ const StatsDialog = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
open={isOpen}
|
open={open}
|
||||||
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'
|
||||||
|
@ -27,7 +27,7 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const UpdateClientDialog = ({
|
const UpdateClientDialog = ({
|
||||||
open,
|
open = false,
|
||||||
clientVersion,
|
clientVersion,
|
||||||
coordinatorVersion,
|
coordinatorVersion,
|
||||||
handleClickClose,
|
handleClickClose,
|
||||||
|
@ -75,7 +75,7 @@ class Chat extends Component {
|
|||||||
this.setState({ connected: false });
|
this.setState({ connected: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setState({ connected: true, connection: connection });
|
this.setState({ connected: true, connection });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,187 +0,0 @@
|
|||||||
import React, { Component } from 'react';
|
|
||||||
import { HashRouter, BrowserRouter, Switch, Route } from 'react-router-dom';
|
|
||||||
|
|
||||||
import UserGenPage from './UserGenPage';
|
|
||||||
import MakerPage from './MakerPage';
|
|
||||||
import BookPage from './BookPage';
|
|
||||||
import OrderPage from './OrderPage';
|
|
||||||
import BottomBar from './BottomBar';
|
|
||||||
|
|
||||||
import { apiClient } from '../services/api';
|
|
||||||
|
|
||||||
export default class HomePage extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
nickname: null,
|
|
||||||
token: null,
|
|
||||||
copiedToken: false,
|
|
||||||
avatarLoaded: false,
|
|
||||||
buyChecked: false,
|
|
||||||
sellChecked: false,
|
|
||||||
type: null,
|
|
||||||
currency: 0,
|
|
||||||
bookCurrencyCode: 'ANY',
|
|
||||||
orders: new Array(),
|
|
||||||
bookLoading: true,
|
|
||||||
bookRefreshing: false,
|
|
||||||
activeOrderId: null,
|
|
||||||
lastOrderId: null,
|
|
||||||
earnedRewards: 0,
|
|
||||||
referralCode: '',
|
|
||||||
lastDayPremium: 0,
|
|
||||||
limits: {},
|
|
||||||
loadingLimits: true,
|
|
||||||
maker: {},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount = () => {
|
|
||||||
if (typeof window !== undefined) {
|
|
||||||
this.setState({
|
|
||||||
windowWidth: window.innerWidth / this.props.theme.typography.fontSize,
|
|
||||||
windowHeight: window.innerHeight / this.props.theme.typography.fontSize,
|
|
||||||
});
|
|
||||||
window.addEventListener('resize', this.onResize);
|
|
||||||
}
|
|
||||||
this.fetchBook(true, false);
|
|
||||||
this.fetchLimits(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
componentWillUnmount = () => {
|
|
||||||
if (typeof window !== undefined) {
|
|
||||||
window.removeEventListener('resize', this.onResize);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
onResize = () => {
|
|
||||||
this.setState({
|
|
||||||
windowWidth: window.innerWidth / this.props.theme.typography.fontSize,
|
|
||||||
windowHeight: window.innerHeight / this.props.theme.typography.fontSize,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
setAppState = (newState) => {
|
|
||||||
this.setState(newState);
|
|
||||||
};
|
|
||||||
|
|
||||||
redirectTo(location) {
|
|
||||||
this.props.history.push(location);
|
|
||||||
}
|
|
||||||
|
|
||||||
getBasename() {
|
|
||||||
if (window.NativeRobosats) {
|
|
||||||
// Only for Android
|
|
||||||
return window.location.pathname;
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchBook = (loading, refreshing) => {
|
|
||||||
this.setState({ bookLoading: loading, bookRefreshing: refreshing });
|
|
||||||
apiClient.get('/api/book/').then((data) =>
|
|
||||||
this.setState({
|
|
||||||
bookLoading: false,
|
|
||||||
bookRefreshing: false,
|
|
||||||
orders: data.not_found ? [] : data,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchLimits = (loading) => {
|
|
||||||
this.setState({ loadingLimits: loading });
|
|
||||||
const limits = apiClient.get('/api/limits/').then((data) => {
|
|
||||||
this.setState({ limits: data, loadingLimits: false });
|
|
||||||
return data;
|
|
||||||
});
|
|
||||||
return limits;
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const fontSize = this.props.theme.typography.fontSize;
|
|
||||||
const fontSizeFactor = fontSize / 14; // default fontSize is 14
|
|
||||||
const Router = window.NativeRobosats ? HashRouter : BrowserRouter;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Router basename={this.getBasename()}>
|
|
||||||
<div className='appCenter'>
|
|
||||||
<Switch>
|
|
||||||
<Route
|
|
||||||
exact
|
|
||||||
path='/'
|
|
||||||
render={(props) => (
|
|
||||||
<UserGenPage
|
|
||||||
{...props}
|
|
||||||
{...this.state}
|
|
||||||
{...this.props}
|
|
||||||
setAppState={this.setAppState}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<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}
|
|
||||||
fetchLimits={this.fetchLimits}
|
|
||||||
setAppState={this.setAppState}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path='/book'
|
|
||||||
render={(props) => (
|
|
||||||
<BookPage
|
|
||||||
{...props}
|
|
||||||
{...this.state}
|
|
||||||
{...this.props}
|
|
||||||
fetchBook={this.fetchBook}
|
|
||||||
fetchLimits={this.fetchLimits}
|
|
||||||
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: `${(this.state.windowWidth / 16) * 14}em`,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<BottomBar
|
|
||||||
redirectTo={this.redirectTo}
|
|
||||||
{...this.state}
|
|
||||||
{...this.props}
|
|
||||||
setAppState={this.setAppState}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Router>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
198
frontend/src/components/Main.tsx
Normal file
198
frontend/src/components/Main.tsx
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { HashRouter, BrowserRouter, Switch, Route, useHistory } from 'react-router-dom';
|
||||||
|
import { useTheme } from '@mui/material';
|
||||||
|
|
||||||
|
import UserGenPage from './UserGenPage';
|
||||||
|
import MakerPage from './MakerPage';
|
||||||
|
import BookPage from './BookPage';
|
||||||
|
import OrderPage from './OrderPage';
|
||||||
|
import BottomBar from './BottomBar';
|
||||||
|
|
||||||
|
import { apiClient } from '../services/api';
|
||||||
|
import checkVer from '../utils/checkVer';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Book,
|
||||||
|
LimitList,
|
||||||
|
Maker,
|
||||||
|
Robot,
|
||||||
|
Info,
|
||||||
|
Settings,
|
||||||
|
Favorites,
|
||||||
|
defaultMaker,
|
||||||
|
defaultRobot,
|
||||||
|
defaultInfo,
|
||||||
|
defaultSettings,
|
||||||
|
} from '../models';
|
||||||
|
|
||||||
|
const getWindowSize = function (fontSize: number) {
|
||||||
|
// returns window size in EM units
|
||||||
|
return {
|
||||||
|
width: window.innerWidth / fontSize,
|
||||||
|
height: window.innerHeight / fontSize,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const Main = (): JSX.Element => {
|
||||||
|
const theme = useTheme();
|
||||||
|
const history = useHistory();
|
||||||
|
const Router = window.NativeRobosats != null ? HashRouter : BrowserRouter;
|
||||||
|
const basename = window.NativeRobosats != null ? window.location.pathname : '';
|
||||||
|
|
||||||
|
// All app data structured
|
||||||
|
const [book, setBook] = useState<Book>({ orders: [], loading: true });
|
||||||
|
const [limits, setLimits] = useState<{ list: LimitList; loading: boolean }>({
|
||||||
|
list: [],
|
||||||
|
loading: true,
|
||||||
|
});
|
||||||
|
const [robot, setRobot] = useState<Robot>(defaultRobot);
|
||||||
|
const [maker, setMaker] = useState<Maker>(defaultMaker);
|
||||||
|
const [info, setInfo] = useState<Info>(defaultInfo);
|
||||||
|
const [fav, setFav] = useState<Favorites>({ type: null, currency: 0 });
|
||||||
|
const [settings, setSettings] = useState<Settings>(defaultSettings);
|
||||||
|
|
||||||
|
const [windowSize, setWindowSize] = useState<{ width: number; height: number }>(
|
||||||
|
getWindowSize(theme.typography.fontSize),
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (typeof window !== undefined) {
|
||||||
|
window.addEventListener('resize', onResize);
|
||||||
|
}
|
||||||
|
fetchBook();
|
||||||
|
fetchLimits();
|
||||||
|
fetchInfo();
|
||||||
|
return () => {
|
||||||
|
if (typeof window !== undefined) {
|
||||||
|
window.removeEventListener('resize', onResize);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onResize = function () {
|
||||||
|
setWindowSize(getWindowSize(theme.typography.fontSize));
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchBook = function () {
|
||||||
|
setBook({ ...book, loading: true });
|
||||||
|
apiClient.get('/api/book/').then((data: any) =>
|
||||||
|
setBook({
|
||||||
|
loading: false,
|
||||||
|
orders: data.not_found ? [] : data,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchLimits = async () => {
|
||||||
|
setLimits({ ...limits, loading: true });
|
||||||
|
const data = apiClient.get('/api/limits/').then((data) => {
|
||||||
|
setLimits({ list: data ?? [], loading: false });
|
||||||
|
return data;
|
||||||
|
});
|
||||||
|
return await data;
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchInfo = function () {
|
||||||
|
apiClient.get('/api/info/').then((data: any) => {
|
||||||
|
const versionInfo: any = checkVer(data.version.major, data.version.minor, data.version.patch);
|
||||||
|
setInfo({
|
||||||
|
...data,
|
||||||
|
openUpdateClient: versionInfo.updateAvailable,
|
||||||
|
coordinatorVersion: versionInfo.coordinatorVersion,
|
||||||
|
clientVersion: versionInfo.clientVersion,
|
||||||
|
});
|
||||||
|
setRobot({
|
||||||
|
...robot,
|
||||||
|
nickname: data.nickname,
|
||||||
|
loading: false,
|
||||||
|
activeOrderId: data.active_order_id ?? null,
|
||||||
|
lastOrderId: data.last_order_id ?? null,
|
||||||
|
referralCode: data.referral_code,
|
||||||
|
tgEnabled: data.tg_enabled,
|
||||||
|
tgBotName: data.tg_bot_name,
|
||||||
|
tgToken: data.tg_token,
|
||||||
|
earnedRewards: data.earned_rewards ?? 0,
|
||||||
|
stealthInvoices: data.wants_stealth,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(robot);
|
||||||
|
return (
|
||||||
|
<Router basename={basename}>
|
||||||
|
<div className='appCenter'>
|
||||||
|
<Switch>
|
||||||
|
<Route
|
||||||
|
exact
|
||||||
|
path='/'
|
||||||
|
render={(props: any) => (
|
||||||
|
<UserGenPage match={props.match} theme={theme} robot={robot} setRobot={setRobot} />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path='/ref/:refCode'
|
||||||
|
render={(props: any) => (
|
||||||
|
<UserGenPage match={props.match} theme={theme} robot={robot} setRobot={setRobot} />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path='/make'
|
||||||
|
render={() => (
|
||||||
|
<MakerPage
|
||||||
|
orders={book.orders}
|
||||||
|
limits={limits}
|
||||||
|
fetchLimits={fetchLimits}
|
||||||
|
maker={maker}
|
||||||
|
setMaker={setMaker}
|
||||||
|
fav={fav}
|
||||||
|
setFav={setFav}
|
||||||
|
windowSize={windowSize}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path='/book'
|
||||||
|
render={() => (
|
||||||
|
<BookPage
|
||||||
|
book={book}
|
||||||
|
fetchBook={fetchBook}
|
||||||
|
limits={limits}
|
||||||
|
fetchLimits={fetchLimits}
|
||||||
|
fav={fav}
|
||||||
|
setFav={setFav}
|
||||||
|
maker={maker}
|
||||||
|
setMaker={setMaker}
|
||||||
|
lastDayPremium={info.last_day_nonkyc_btc_premium}
|
||||||
|
windowSize={windowSize}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path='/order/:orderId'
|
||||||
|
render={(props: any) => <OrderPage theme={theme} history={history} {...props} />}
|
||||||
|
/>
|
||||||
|
</Switch>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '2.5em',
|
||||||
|
position: 'fixed',
|
||||||
|
bottom: 0,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<BottomBar
|
||||||
|
theme={theme}
|
||||||
|
windowSize={windowSize}
|
||||||
|
redirectTo={(location: string) => history.push(location)}
|
||||||
|
robot={robot}
|
||||||
|
setRobot={setRobot}
|
||||||
|
info={info}
|
||||||
|
setInfo={setInfo}
|
||||||
|
fetchInfo={fetchInfo}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Router>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Main;
|
@ -24,7 +24,7 @@ import {
|
|||||||
IconButton,
|
IconButton,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
|
|
||||||
import { LimitList, Maker, defaultMaker } from '../../models';
|
import { LimitList, Maker, Favorites, defaultMaker } from '../../models';
|
||||||
|
|
||||||
import { LocalizationProvider, TimePicker } from '@mui/x-date-pickers';
|
import { LocalizationProvider, TimePicker } from '@mui/x-date-pickers';
|
||||||
import DateFnsUtils from '@date-io/date-fns';
|
import DateFnsUtils from '@date-io/date-fns';
|
||||||
@ -43,14 +43,12 @@ import { SelfImprovement, Lock, HourglassTop, DeleteSweep, Edit } from '@mui/ico
|
|||||||
import { LoadingButton } from '@mui/lab';
|
import { LoadingButton } from '@mui/lab';
|
||||||
|
|
||||||
interface MakerFormProps {
|
interface MakerFormProps {
|
||||||
limits: LimitList;
|
limits: { list: LimitList; loading: boolean };
|
||||||
fetchLimits: (loading) => void;
|
fetchLimits: () => void;
|
||||||
loadingLimits: boolean;
|
|
||||||
pricingMethods: boolean;
|
pricingMethods: boolean;
|
||||||
maker: Maker;
|
maker: Maker;
|
||||||
type: number;
|
fav: Favorites;
|
||||||
currency: number;
|
setFav: (state: Favorites) => void;
|
||||||
setAppState: (state: object) => void;
|
|
||||||
setMaker: (state: Maker) => void;
|
setMaker: (state: Maker) => void;
|
||||||
disableRequest?: boolean;
|
disableRequest?: boolean;
|
||||||
collapseAll?: boolean;
|
collapseAll?: boolean;
|
||||||
@ -62,11 +60,9 @@ interface MakerFormProps {
|
|||||||
const MakerForm = ({
|
const MakerForm = ({
|
||||||
limits,
|
limits,
|
||||||
fetchLimits,
|
fetchLimits,
|
||||||
loadingLimits,
|
|
||||||
pricingMethods,
|
pricingMethods,
|
||||||
currency,
|
fav,
|
||||||
type,
|
setFav,
|
||||||
setAppState,
|
|
||||||
maker,
|
maker,
|
||||||
setMaker,
|
setMaker,
|
||||||
disableRequest = false,
|
disableRequest = false,
|
||||||
@ -79,7 +75,6 @@ const MakerForm = ({
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const [badRequest, setBadRequest] = useState<string | null>(null);
|
const [badRequest, setBadRequest] = useState<string | null>(null);
|
||||||
const [advancedOptions, setAdvancedOptions] = useState<boolean>(false);
|
|
||||||
const [amountLimits, setAmountLimits] = useState<number[]>([1, 1000]);
|
const [amountLimits, setAmountLimits] = useState<number[]>([1, 1000]);
|
||||||
const [satoshisLimits, setSatoshisLimits] = useState<number[]>([20000, 4000000]);
|
const [satoshisLimits, setSatoshisLimits] = useState<number[]>([20000, 4000000]);
|
||||||
const [currentPrice, setCurrentPrice] = useState<number | string>('...');
|
const [currentPrice, setCurrentPrice] = useState<number | string>('...');
|
||||||
@ -93,27 +88,26 @@ const MakerForm = ({
|
|||||||
const amountSafeThresholds = [1.03, 0.98];
|
const amountSafeThresholds = [1.03, 0.98];
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setCurrencyCode(currencyDict[currency == 0 ? 1 : currency]);
|
setCurrencyCode(currencyDict[fav.currency == 0 ? 1 : fav.currency]);
|
||||||
if (Object.keys(limits).length === 0) {
|
if (Object.keys(limits.list).length === 0) {
|
||||||
setAppState({ loadingLimits: true });
|
fetchLimits().then((data) => {
|
||||||
fetchLimits(true).then((data) => {
|
updateAmountLimits(data, fav.currency, maker.premium);
|
||||||
updateAmountLimits(data, currency, maker.premium);
|
updateCurrentPrice(data, fav.currency, maker.premium);
|
||||||
updateCurrentPrice(data, currency, maker.premium);
|
|
||||||
updateSatoshisLimits(data);
|
updateSatoshisLimits(data);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
updateAmountLimits(limits, currency, maker.premium);
|
updateAmountLimits(limits.list, fav.currency, maker.premium);
|
||||||
updateCurrentPrice(limits, currency, maker.premium);
|
updateCurrentPrice(limits.list, fav.currency, maker.premium);
|
||||||
updateSatoshisLimits(limits);
|
updateSatoshisLimits(limits.list);
|
||||||
|
|
||||||
fetchLimits(false);
|
fetchLimits();
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const updateAmountLimits = function (limits: LimitList, currency: number, premium: number) {
|
const updateAmountLimits = function (limitList: LimitList, currency: number, premium: number) {
|
||||||
const index = currency === 0 ? 1 : currency;
|
const index = currency == 0 ? 1 : currency;
|
||||||
let minAmountLimit: number = limits[index].min_amount * (1 + premium / 100);
|
let minAmountLimit: number = limitList[index].min_amount * (1 + premium / 100);
|
||||||
let maxAmountLimit: number = limits[index].max_amount * (1 + premium / 100);
|
let maxAmountLimit: number = limitList[index].max_amount * (1 + premium / 100);
|
||||||
|
|
||||||
// apply thresholds to ensure good request
|
// apply thresholds to ensure good request
|
||||||
minAmountLimit = minAmountLimit * amountSafeThresholds[0];
|
minAmountLimit = minAmountLimit * amountSafeThresholds[0];
|
||||||
@ -121,19 +115,19 @@ const MakerForm = ({
|
|||||||
setAmountLimits([minAmountLimit, maxAmountLimit]);
|
setAmountLimits([minAmountLimit, maxAmountLimit]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateSatoshisLimits = function (limits: LimitList) {
|
const updateSatoshisLimits = function (limitList: LimitList) {
|
||||||
const minAmount: number = limits[1000].min_amount * 100000000;
|
const minAmount: number = limitList[1000].min_amount * 100000000;
|
||||||
const maxAmount: number = limits[1000].max_amount * 100000000;
|
const maxAmount: number = limitList[1000].max_amount * 100000000;
|
||||||
setSatoshisLimits([minAmount, maxAmount]);
|
setSatoshisLimits([minAmount, maxAmount]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateCurrentPrice = function (limits: LimitList, currency: number, premium: number) {
|
const updateCurrentPrice = function (limitsList: LimitList, currency: number, premium: number) {
|
||||||
const index = currency === 0 ? 1 : currency;
|
const index = currency == 0 ? 1 : currency;
|
||||||
let price = '...';
|
let price = '...';
|
||||||
if (maker.is_explicit && maker.amount > 0 && maker.satoshis > 0) {
|
if (maker.isExplicit && maker.amount > 0 && maker.satoshis > 0) {
|
||||||
price = maker.amount / (maker.satoshis / 100000000);
|
price = maker.amount / (maker.satoshis / 100000000);
|
||||||
} else if (!maker.is_explicit) {
|
} else if (!maker.is_explicit) {
|
||||||
price = limits[index].price * (1 + premium / 100);
|
price = limitsList[index].price * (1 + premium / 100);
|
||||||
}
|
}
|
||||||
setCurrentPrice(parseFloat(Number(price).toPrecision(5)));
|
setCurrentPrice(parseFloat(Number(price).toPrecision(5)));
|
||||||
};
|
};
|
||||||
@ -141,17 +135,17 @@ const MakerForm = ({
|
|||||||
const handleCurrencyChange = function (newCurrency: number) {
|
const handleCurrencyChange = function (newCurrency: number) {
|
||||||
const currencyCode: string = currencyDict[newCurrency];
|
const currencyCode: string = currencyDict[newCurrency];
|
||||||
setCurrencyCode(currencyCode);
|
setCurrencyCode(currencyCode);
|
||||||
setAppState({
|
setFav({
|
||||||
|
...fav,
|
||||||
currency: newCurrency,
|
currency: newCurrency,
|
||||||
bookCurrencyCode: currencyCode,
|
|
||||||
});
|
});
|
||||||
updateAmountLimits(limits, newCurrency, maker.premium);
|
updateAmountLimits(limits.list, newCurrency, maker.premium);
|
||||||
updateCurrentPrice(limits, newCurrency, maker.premium);
|
updateCurrentPrice(limits.list, newCurrency, maker.premium);
|
||||||
if (advancedOptions) {
|
if (maker.advancedOptions) {
|
||||||
setMaker({
|
setMaker({
|
||||||
...maker,
|
...maker,
|
||||||
minAmount: parseFloat(Number(limits[newCurrency].max_amount * 0.25).toPrecision(2)),
|
minAmount: parseFloat(Number(limits.list[newCurrency].max_amount * 0.25).toPrecision(2)),
|
||||||
maxAmount: parseFloat(Number(limits[newCurrency].max_amount * 0.75).toPrecision(2)),
|
maxAmount: parseFloat(Number(limits.list[newCurrency].max_amount * 0.75).toPrecision(2)),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -198,8 +192,8 @@ const MakerForm = ({
|
|||||||
badPremiumText = t('Must be more than {{min}}%', { min });
|
badPremiumText = t('Must be more than {{min}}%', { min });
|
||||||
premium = -99.99;
|
premium = -99.99;
|
||||||
}
|
}
|
||||||
updateCurrentPrice(limits, currency, premium);
|
updateCurrentPrice(limits.list, fav.currency, premium);
|
||||||
updateAmountLimits(limits, currency, premium);
|
updateAmountLimits(limits.list, fav.currency, premium);
|
||||||
setMaker({
|
setMaker({
|
||||||
...maker,
|
...maker,
|
||||||
premium,
|
premium,
|
||||||
@ -235,7 +229,7 @@ const MakerForm = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleClickExplicit = function () {
|
const handleClickExplicit = function () {
|
||||||
if (!advancedOptions) {
|
if (!maker.advancedOptions) {
|
||||||
setMaker({
|
setMaker({
|
||||||
...maker,
|
...maker,
|
||||||
isExplicit: true,
|
isExplicit: true,
|
||||||
@ -247,12 +241,12 @@ const MakerForm = ({
|
|||||||
if (!disableRequest) {
|
if (!disableRequest) {
|
||||||
setSubmittingRequest(true);
|
setSubmittingRequest(true);
|
||||||
const body = {
|
const body = {
|
||||||
type: type == 0 ? 1 : 0,
|
type: fav.type == 0 ? 1 : 0,
|
||||||
currency: currency == 0 ? 1 : currency,
|
currency: fav.currency == 0 ? 1 : fav.currency,
|
||||||
amount: advancedOptions ? null : maker.amount,
|
amount: maker.advancedOptions ? null : maker.amount,
|
||||||
has_range: advancedOptions,
|
has_range: maker.advancedOptions,
|
||||||
min_amount: advancedOptions ? maker.minAmount : null,
|
min_amount: maker.advancedOptions ? maker.minAmount : null,
|
||||||
max_amount: advancedOptions ? maker.maxAmount : null,
|
max_amount: maker.advancedOptions ? maker.maxAmount : null,
|
||||||
payment_method:
|
payment_method:
|
||||||
maker.paymentMethodsText === '' ? 'not specified' : maker.paymentMethodsText,
|
maker.paymentMethodsText === '' ? 'not specified' : maker.paymentMethodsText,
|
||||||
is_explicit: maker.isExplicit,
|
is_explicit: maker.isExplicit,
|
||||||
@ -300,13 +294,12 @@ const MakerForm = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleClickAdvanced = function () {
|
const handleClickAdvanced = function () {
|
||||||
if (advancedOptions) {
|
if (maker.advancedOptions) {
|
||||||
handleClickRelative();
|
handleClickRelative();
|
||||||
|
setMaker({ ...maker, advancedOptions: false });
|
||||||
} else {
|
} else {
|
||||||
resetRange();
|
resetRange(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
setAdvancedOptions(!advancedOptions);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const minAmountError = function () {
|
const minAmountError = function () {
|
||||||
@ -327,17 +320,18 @@ const MakerForm = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const resetRange = function () {
|
const resetRange = function (advancedOptions: boolean) {
|
||||||
const index = currency === 0 ? 1 : currency;
|
const index = fav.currency === 0 ? 1 : fav.currency;
|
||||||
const minAmount = maker.amount
|
const minAmount = maker.amount
|
||||||
? parseFloat((maker.amount / 2).toPrecision(2))
|
? parseFloat((maker.amount / 2).toPrecision(2))
|
||||||
: parseFloat(Number(limits[index].max_amount * 0.25).toPrecision(2));
|
: parseFloat(Number(limits.list[index].max_amount * 0.25).toPrecision(2));
|
||||||
const maxAmount = maker.amount
|
const maxAmount = maker.amount
|
||||||
? parseFloat(maker.amount)
|
? parseFloat(maker.amount)
|
||||||
: parseFloat(Number(limits[index].max_amount * 0.75).toPrecision(2));
|
: parseFloat(Number(limits.list[index].max_amount * 0.75).toPrecision(2));
|
||||||
|
|
||||||
setMaker({
|
setMaker({
|
||||||
...maker,
|
...maker,
|
||||||
|
advancedOptions,
|
||||||
minAmount,
|
minAmount,
|
||||||
maxAmount,
|
maxAmount,
|
||||||
});
|
});
|
||||||
@ -379,20 +373,20 @@ const MakerForm = ({
|
|||||||
|
|
||||||
const disableSubmit = function () {
|
const disableSubmit = function () {
|
||||||
return (
|
return (
|
||||||
type == null ||
|
fav.type == null ||
|
||||||
(maker.amount != '' &&
|
(maker.amount != '' &&
|
||||||
!advancedOptions &&
|
!maker.advancedOptions &&
|
||||||
(maker.amount < amountLimits[0] || maker.amount > amountLimits[1])) ||
|
(maker.amount < amountLimits[0] || maker.amount > amountLimits[1])) ||
|
||||||
(maker.amount == null && (!advancedOptions || loadingLimits)) ||
|
(maker.amount == null && (!maker.advancedOptions || limits.loading)) ||
|
||||||
(advancedOptions && (minAmountError() || maxAmountError())) ||
|
(maker.advancedOptions && (minAmountError() || maxAmountError())) ||
|
||||||
(maker.amount <= 0 && !advancedOptions) ||
|
(maker.amount <= 0 && !maker.advancedOptions) ||
|
||||||
(maker.isExplicit && (maker.badSatoshisText != '' || maker.satoshis == '')) ||
|
(maker.isExplicit && (maker.badSatoshisText != '' || maker.satoshis == '')) ||
|
||||||
(!maker.isExplicit && maker.badPremiumText != '')
|
(!maker.isExplicit && maker.badPremiumText != '')
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const clearMaker = function () {
|
const clearMaker = function () {
|
||||||
setAppState({ type: null });
|
setFav({ ...fav, type: null });
|
||||||
setMaker(defaultMaker);
|
setMaker(defaultMaker);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -404,8 +398,12 @@ const MakerForm = ({
|
|||||||
align='center'
|
align='center'
|
||||||
color={disableSubmit() ? 'text.secondary' : 'text.primary'}
|
color={disableSubmit() ? 'text.secondary' : 'text.primary'}
|
||||||
>
|
>
|
||||||
{type == null ? t('Order for ') : type == 1 ? t('Buy order for ') : t('Sell order for ')}
|
{fav.type == null
|
||||||
{advancedOptions && maker.minAmount != ''
|
? t('Order for ')
|
||||||
|
: fav.type == 1
|
||||||
|
? t('Buy order for ')
|
||||||
|
: t('Sell order for ')}
|
||||||
|
{maker.advancedOptions && maker.minAmount != ''
|
||||||
? pn(maker.minAmount) + '-' + pn(maker.maxAmount)
|
? pn(maker.minAmount) + '-' + pn(maker.maxAmount)
|
||||||
: pn(maker.amount)}
|
: pn(maker.amount)}
|
||||||
{' ' + currencyCode}
|
{' ' + currencyCode}
|
||||||
@ -437,12 +435,12 @@ const MakerForm = ({
|
|||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<ConfirmationDialogs />
|
<ConfirmationDialogs />
|
||||||
<Collapse in={loadingLimits}>
|
<Collapse in={limits.list.length == 0}>
|
||||||
<div style={{ display: loadingLimits ? '' : 'none' }}>
|
<div style={{ display: limits.list.length == 0 ? '' : 'none' }}>
|
||||||
<LinearProgress />
|
<LinearProgress />
|
||||||
</div>
|
</div>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
<Collapse in={!(loadingLimits || collapseAll)}>
|
<Collapse in={!(limits.list.length == 0 || collapseAll)}>
|
||||||
<Grid container justifyContent='space-between' spacing={0} sx={{ maxHeight: '1em' }}>
|
<Grid container justifyContent='space-between' spacing={0} sx={{ maxHeight: '1em' }}>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<IconButton
|
<IconButton
|
||||||
@ -478,8 +476,8 @@ const MakerForm = ({
|
|||||||
>
|
>
|
||||||
<Switch
|
<Switch
|
||||||
size='small'
|
size='small'
|
||||||
disabled={loadingLimits}
|
disabled={limits.list.length == 0}
|
||||||
checked={advancedOptions}
|
checked={maker.advancedOptions}
|
||||||
onChange={handleClickAdvanced}
|
onChange={handleClickAdvanced}
|
||||||
/>
|
/>
|
||||||
<SelfImprovement sx={{ color: 'text.secondary' }} />
|
<SelfImprovement sx={{ color: 'text.secondary' }} />
|
||||||
@ -499,17 +497,18 @@ const MakerForm = ({
|
|||||||
<div style={{ textAlign: 'center' }}>
|
<div style={{ textAlign: 'center' }}>
|
||||||
<ButtonGroup>
|
<ButtonGroup>
|
||||||
<Button
|
<Button
|
||||||
size={advancedOptions ? 'small' : 'large'}
|
size={maker.advancedOptions ? 'small' : 'large'}
|
||||||
variant='contained'
|
variant='contained'
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setAppState({
|
setFav({
|
||||||
|
...fav,
|
||||||
type: 1,
|
type: 1,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
disableElevation={type == 1}
|
disableElevation={fav.type == 1}
|
||||||
sx={{
|
sx={{
|
||||||
backgroundColor: type == 1 ? 'primary.main' : 'background.paper',
|
backgroundColor: fav.type == 1 ? 'primary.main' : 'background.paper',
|
||||||
color: type == 1 ? 'background.paper' : 'text.secondary',
|
color: fav.type == 1 ? 'background.paper' : 'text.secondary',
|
||||||
':hover': {
|
':hover': {
|
||||||
color: 'background.paper',
|
color: 'background.paper',
|
||||||
},
|
},
|
||||||
@ -518,18 +517,19 @@ const MakerForm = ({
|
|||||||
{t('Buy')}
|
{t('Buy')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
size={advancedOptions ? 'small' : 'large'}
|
size={maker.advancedOptions ? 'small' : 'large'}
|
||||||
variant='contained'
|
variant='contained'
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setAppState({
|
setFav({
|
||||||
|
...fav,
|
||||||
type: 0,
|
type: 0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
disableElevation={type == 0}
|
disableElevation={fav.type == 0}
|
||||||
color='secondary'
|
color='secondary'
|
||||||
sx={{
|
sx={{
|
||||||
backgroundColor: type == 0 ? 'secondary.main' : 'background.paper',
|
backgroundColor: fav.type == 0 ? 'secondary.main' : 'background.paper',
|
||||||
color: type == 0 ? 'background.secondary' : 'text.secondary',
|
color: fav.type == 0 ? 'background.secondary' : 'text.secondary',
|
||||||
':hover': {
|
':hover': {
|
||||||
color: 'background.paper',
|
color: 'background.paper',
|
||||||
},
|
},
|
||||||
@ -543,11 +543,11 @@ const MakerForm = ({
|
|||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Collapse in={advancedOptions}>
|
<Collapse in={maker.advancedOptions}>
|
||||||
<AmountRange
|
<AmountRange
|
||||||
minAmount={maker.minAmount}
|
minAmount={maker.minAmount}
|
||||||
handleRangeAmountChange={handleRangeAmountChange}
|
handleRangeAmountChange={handleRangeAmountChange}
|
||||||
currency={currency}
|
currency={fav.currency}
|
||||||
currencyCode={currencyCode}
|
currencyCode={currencyCode}
|
||||||
handleCurrencyChange={handleCurrencyChange}
|
handleCurrencyChange={handleCurrencyChange}
|
||||||
amountLimits={amountLimits}
|
amountLimits={amountLimits}
|
||||||
@ -558,7 +558,7 @@ const MakerForm = ({
|
|||||||
handleMaxAmountChange={handleMaxAmountChange}
|
handleMaxAmountChange={handleMaxAmountChange}
|
||||||
/>
|
/>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
<Collapse in={!advancedOptions}>
|
<Collapse in={!maker.advancedOptions}>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Grid container alignItems='stretch' style={{ display: 'flex' }}>
|
<Grid container alignItems='stretch' style={{ display: 'flex' }}>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
@ -571,8 +571,8 @@ const MakerForm = ({
|
|||||||
>
|
>
|
||||||
<TextField
|
<TextField
|
||||||
fullWidth
|
fullWidth
|
||||||
disabled={advancedOptions}
|
disabled={maker.advancedOptions}
|
||||||
variant={advancedOptions ? 'filled' : 'outlined'}
|
variant={maker.advancedOptions ? 'filled' : 'outlined'}
|
||||||
error={
|
error={
|
||||||
maker.amount != '' &&
|
maker.amount != '' &&
|
||||||
(maker.amount < amountLimits[0] || maker.amount > amountLimits[1])
|
(maker.amount < amountLimits[0] || maker.amount > amountLimits[1])
|
||||||
@ -613,7 +613,7 @@ const MakerForm = ({
|
|||||||
inputProps={{
|
inputProps={{
|
||||||
style: { textAlign: 'center' },
|
style: { textAlign: 'center' },
|
||||||
}}
|
}}
|
||||||
value={currency == 0 ? 1 : currency}
|
value={fav.currency == 0 ? 1 : fav.currency}
|
||||||
onChange={(e) => handleCurrencyChange(e.target.value)}
|
onChange={(e) => handleCurrencyChange(e.target.value)}
|
||||||
>
|
>
|
||||||
{Object.entries(currencyDict).map(([key, value]) => (
|
{Object.entries(currencyDict).map(([key, value]) => (
|
||||||
@ -635,10 +635,10 @@ const MakerForm = ({
|
|||||||
<AutocompletePayments
|
<AutocompletePayments
|
||||||
onAutocompleteChange={handlePaymentMethodChange}
|
onAutocompleteChange={handlePaymentMethodChange}
|
||||||
// listBoxProps={{ sx: { width: '15.3em', maxHeight: '20em' } }}
|
// listBoxProps={{ sx: { width: '15.3em', maxHeight: '20em' } }}
|
||||||
optionsType={currency == 1000 ? 'swap' : 'fiat'}
|
optionsType={fav.currency == 1000 ? 'swap' : 'fiat'}
|
||||||
error={maker.badPaymentMethod}
|
error={maker.badPaymentMethod}
|
||||||
helperText={maker.badPaymentMethod ? t('Must be shorter than 65 characters') : ''}
|
helperText={maker.badPaymentMethod ? t('Must be shorter than 65 characters') : ''}
|
||||||
label={currency == 1000 ? t('Swap Destination(s)') : t('Fiat Payment Method(s)')}
|
label={fav.currency == 1000 ? t('Swap Destination(s)') : t('Fiat Payment Method(s)')}
|
||||||
tooltipTitle={t(
|
tooltipTitle={t(
|
||||||
'Enter your preferred fiat payment methods. Fast methods are highly recommended.',
|
'Enter your preferred fiat payment methods. Fast methods are highly recommended.',
|
||||||
)}
|
)}
|
||||||
@ -649,7 +649,7 @@ const MakerForm = ({
|
|||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
{!advancedOptions && pricingMethods ? (
|
{!maker.advancedOptions && pricingMethods ? (
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
@ -691,7 +691,7 @@ const MakerForm = ({
|
|||||||
title={t('Set a fix amount of satoshis')}
|
title={t('Set a fix amount of satoshis')}
|
||||||
>
|
>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
disabled={advancedOptions}
|
disabled={maker.advancedOptions}
|
||||||
value='explicit'
|
value='explicit'
|
||||||
control={<Radio color='secondary' />}
|
control={<Radio color='secondary' />}
|
||||||
label={t('Exact')}
|
label={t('Exact')}
|
||||||
@ -748,7 +748,7 @@ const MakerForm = ({
|
|||||||
</div>
|
</div>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Collapse in={advancedOptions}>
|
<Collapse in={maker.advancedOptions}>
|
||||||
<Grid container spacing={1}>
|
<Grid container spacing={1}>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<LocalizationProvider dateAdapter={DateFnsUtils}>
|
<LocalizationProvider dateAdapter={DateFnsUtils}>
|
||||||
@ -944,7 +944,7 @@ const MakerForm = ({
|
|||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Collapse in={!loadingLimits}>
|
<Collapse in={!(limits.list.length == 0)}>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
placement='top'
|
placement='top'
|
||||||
enterTouchDelay={0}
|
enterTouchDelay={0}
|
||||||
|
@ -2,7 +2,7 @@ import React, { useState } from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Button, Grid, Paper, Collapse, Typography } from '@mui/material';
|
import { Button, Grid, Paper, Collapse, Typography } from '@mui/material';
|
||||||
|
|
||||||
import { LimitList, Maker, Order, defaultMaker } from '../../models';
|
import { LimitList, Maker, Order, Favorites, defaultMaker } from '../../models';
|
||||||
import MakerForm from './MakerForm';
|
import MakerForm from './MakerForm';
|
||||||
import BookTable from '../BookPage/BookTable';
|
import BookTable from '../BookPage/BookTable';
|
||||||
|
|
||||||
@ -10,38 +10,35 @@ import { useHistory } from 'react-router-dom';
|
|||||||
import filterOrders from '../../utils/filterOrders';
|
import filterOrders from '../../utils/filterOrders';
|
||||||
|
|
||||||
interface MakerPageProps {
|
interface MakerPageProps {
|
||||||
limits: LimitList;
|
limits: { list: LimitList; loading: boolean };
|
||||||
fetchLimits: () => void;
|
fetchLimits: () => void;
|
||||||
orders: Order[];
|
orders: Order[];
|
||||||
loadingLimits: boolean;
|
fav: Favorites;
|
||||||
type: number;
|
maker: Maker;
|
||||||
windowHeight: number;
|
setFav: (state: Favorites) => void;
|
||||||
windowWidth: number;
|
setMaker: (state: Maker) => void;
|
||||||
currency: number;
|
windowSize: { width: number; height: number };
|
||||||
setAppState: (state: object) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const MakerPage = ({
|
const MakerPage = ({
|
||||||
limits,
|
limits,
|
||||||
fetchLimits,
|
fetchLimits,
|
||||||
orders,
|
orders,
|
||||||
loadingLimits,
|
fav,
|
||||||
currency,
|
maker,
|
||||||
type,
|
setFav,
|
||||||
setAppState,
|
setMaker,
|
||||||
windowHeight,
|
windowSize,
|
||||||
windowWidth,
|
|
||||||
}: MakerPageProps): JSX.Element => {
|
}: MakerPageProps): JSX.Element => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
const [maker, setMaker] = useState<Maker>(defaultMaker);
|
const maxHeight = windowSize.height * 0.85 - 7;
|
||||||
const maxHeight = windowHeight ? windowHeight * 0.85 - 7 : 1000;
|
|
||||||
const [showMatches, setShowMatches] = useState<boolean>(false);
|
const [showMatches, setShowMatches] = useState<boolean>(false);
|
||||||
|
|
||||||
const matches = filterOrders({
|
const matches = filterOrders({
|
||||||
orders,
|
orders,
|
||||||
baseFilter: { currency: currency == 0 ? 1 : currency, type },
|
baseFilter: { currency: fav.currency === 0 ? 1 : fav.currency, type: fav.type },
|
||||||
paymentMethods: maker.paymentMethods,
|
paymentMethods: maker.paymentMethods,
|
||||||
amountFilter: {
|
amountFilter: {
|
||||||
amount: maker.amount,
|
amount: maker.amount,
|
||||||
@ -61,10 +58,11 @@ const MakerPage = ({
|
|||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<BookTable
|
<BookTable
|
||||||
orders={matches.slice(0, matches.length > 4 ? 4 : matches.length)}
|
book={{
|
||||||
type={type}
|
orders: matches.slice(0, matches.length > 4 ? 4 : matches.length),
|
||||||
currency={currency}
|
loading: false,
|
||||||
maxWidth={Math.min(windowWidth, 60)} // EM units
|
}}
|
||||||
|
maxWidth={Math.min(windowSize.width, 60)} // EM units
|
||||||
maxHeight={Math.min(matches.length * 3.25 + 3.575, 16.575)} // EM units
|
maxHeight={Math.min(matches.length * 3.25 + 3.575, 16.575)} // EM units
|
||||||
defaultFullscreen={false}
|
defaultFullscreen={false}
|
||||||
showControls={false}
|
showControls={false}
|
||||||
@ -82,13 +80,11 @@ const MakerPage = ({
|
|||||||
<MakerForm
|
<MakerForm
|
||||||
limits={limits}
|
limits={limits}
|
||||||
fetchLimits={fetchLimits}
|
fetchLimits={fetchLimits}
|
||||||
loadingLimits={loadingLimits}
|
|
||||||
pricingMethods={false}
|
pricingMethods={false}
|
||||||
setAppState={setAppState}
|
fav={fav}
|
||||||
|
setFav={setFav}
|
||||||
maker={maker}
|
maker={maker}
|
||||||
setMaker={setMaker}
|
setMaker={setMaker}
|
||||||
type={type}
|
|
||||||
currency={currency}
|
|
||||||
disableRequest={matches.length > 0 && !showMatches}
|
disableRequest={matches.length > 0 && !showMatches}
|
||||||
collapseAll={showMatches}
|
collapseAll={showMatches}
|
||||||
onSubmit={() => setShowMatches(matches.length > 0)}
|
onSubmit={() => setShowMatches(matches.length > 0)}
|
||||||
|
@ -525,10 +525,7 @@ class OrderPage extends Component {
|
|||||||
<StoreTokenDialog
|
<StoreTokenDialog
|
||||||
open={this.state.openStoreToken}
|
open={this.state.openStoreToken}
|
||||||
onClose={() => this.setState({ openStoreToken: false })}
|
onClose={() => this.setState({ openStoreToken: false })}
|
||||||
onClickCopy={() =>
|
onClickCopy={() => systemClient.copyToClipboard(systemClient.getCookie('robot_token'))}
|
||||||
systemClient.copyToClipboard(systemClient.getCookie('robot_token')) &
|
|
||||||
this.props.setAppState({ copiedToken: true })
|
|
||||||
}
|
|
||||||
copyIconColor={this.props.copiedToken ? 'inherit' : 'primary'}
|
copyIconColor={this.props.copiedToken ? 'inherit' : 'primary'}
|
||||||
onClickBack={() => this.setState({ openStoreToken: false })}
|
onClickBack={() => this.setState({ openStoreToken: false })}
|
||||||
onClickDone={() =>
|
onClickDone={() =>
|
||||||
|
@ -11,7 +11,6 @@ import {
|
|||||||
IconButton,
|
IconButton,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import SmoothImage from 'react-smooth-image';
|
|
||||||
import { InfoDialog } from './Dialogs';
|
import { InfoDialog } from './Dialogs';
|
||||||
|
|
||||||
import SmartToyIcon from '@mui/icons-material/SmartToy';
|
import SmartToyIcon from '@mui/icons-material/SmartToy';
|
||||||
@ -35,7 +34,7 @@ class UserGenPage extends Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
openInfo: false,
|
openInfo: false,
|
||||||
tokenHasChanged: false,
|
tokenHasChanged: false,
|
||||||
token: '',
|
inputToken: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
this.refCode = this.props.match.params.refCode;
|
this.refCode = this.props.match.params.refCode;
|
||||||
@ -44,19 +43,18 @@ 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.robot.nickname != null) {
|
||||||
this.setState({
|
this.setState({
|
||||||
token: this.props.token ? this.props.token : '',
|
inputToken: this.props.robot.token ? this.props.robot.token : '',
|
||||||
loadingRobot: false,
|
|
||||||
});
|
});
|
||||||
} else if (window.NativeRobosats && systemClient.getCookie('robot_token')) {
|
} else if (window.NativeRobosats && systemClient.getCookie('robot_token')) {
|
||||||
const token = systemClient.getCookie('robot_token');
|
const token = systemClient.getCookie('robot_token');
|
||||||
this.setState({ token });
|
this.setState({ inputToken: token });
|
||||||
this.getGeneratedUser(token);
|
this.getGeneratedUser(token);
|
||||||
} else {
|
} else {
|
||||||
const newToken = genBase62Token(36);
|
const newToken = genBase62Token(36);
|
||||||
this.setState({
|
this.setState({
|
||||||
token: newToken,
|
inputToken: newToken,
|
||||||
});
|
});
|
||||||
this.getGeneratedUser(newToken);
|
this.getGeneratedUser(newToken);
|
||||||
}
|
}
|
||||||
@ -65,6 +63,7 @@ class UserGenPage extends Component {
|
|||||||
getGeneratedUser = (token) => {
|
getGeneratedUser = (token) => {
|
||||||
const strength = tokenStrength(token);
|
const strength = tokenStrength(token);
|
||||||
const refCode = this.refCode;
|
const refCode = this.refCode;
|
||||||
|
this.props.setRobot({ ...this.props.robot, loading: true });
|
||||||
|
|
||||||
const requestBody = genKey(token).then(function (key) {
|
const requestBody = genKey(token).then(function (key) {
|
||||||
return {
|
return {
|
||||||
@ -79,46 +78,44 @@ class UserGenPage extends Component {
|
|||||||
});
|
});
|
||||||
requestBody.then((body) =>
|
requestBody.then((body) =>
|
||||||
apiClient.post('/api/user/', body).then((data) => {
|
apiClient.post('/api/user/', body).then((data) => {
|
||||||
this.setState({
|
|
||||||
bit_entropy: data.token_bits_entropy,
|
|
||||||
shannon_entropy: data.token_shannon_entropy,
|
|
||||||
bad_request: data.bad_request,
|
|
||||||
found: data.found,
|
|
||||||
loadingRobot: false,
|
|
||||||
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.setRobot({
|
||||||
|
...this.props.robot,
|
||||||
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 ?? 0,
|
||||||
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.setRobot({
|
||||||
|
...this.props.robot,
|
||||||
nickname: data.nickname,
|
nickname: data.nickname,
|
||||||
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 ?? 0,
|
||||||
stealthInvoices: data.wants_stealth,
|
stealthInvoices: data.wants_stealth,
|
||||||
tgEnabled: data.tg_enabled,
|
tgEnabled: data.tg_enabled,
|
||||||
tgBotName: data.tg_bot_name,
|
tgBotName: data.tg_bot_name,
|
||||||
tgToken: data.tg_token,
|
tgToken: data.tg_token,
|
||||||
|
bitsEntropy: data.token_bits_entropy,
|
||||||
|
shannonEntropy: data.token_shannon_entropy,
|
||||||
|
pub_key: data.public_key,
|
||||||
|
enc_priv_key: data.encrypted_private_key,
|
||||||
}) &
|
}) &
|
||||||
systemClient.setCookie('robot_token', token) &
|
systemClient.setCookie('robot_token', token) &
|
||||||
systemClient.setCookie('pub_key', data.public_key.split('\n').join('\\')) &
|
systemClient.setCookie('pub_key', data.public_key.split('\n').join('\\')) &
|
||||||
systemClient.setCookie(
|
systemClient.setCookie(
|
||||||
'enc_priv_key',
|
'enc_priv_key',
|
||||||
data.encrypted_private_key.split('\n').join('\\'),
|
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.setRobot({ ...this.props.robot, copiedToken: true }) : null;
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -133,26 +130,27 @@ class UserGenPage extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleClickNewRandomToken = () => {
|
handleClickNewRandomToken = () => {
|
||||||
const token = genBase62Token(36);
|
const inputToken = genBase62Token(36);
|
||||||
this.setState({
|
this.setState({
|
||||||
token,
|
inputToken,
|
||||||
tokenHasChanged: true,
|
tokenHasChanged: true,
|
||||||
});
|
});
|
||||||
this.props.setAppState({ copiedToken: true });
|
this.props.setRobot({ ...this.props.robot, copiedToken: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
handleChangeToken = (e) => {
|
handleChangeToken = (e) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
token: e.target.value.split(' ').join(''),
|
inputToken: e.target.value.split(' ').join(''),
|
||||||
tokenHasChanged: true,
|
tokenHasChanged: true,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
handleClickSubmitToken = () => {
|
handleClickSubmitToken = () => {
|
||||||
this.delGeneratedUser();
|
this.delGeneratedUser();
|
||||||
this.getGeneratedUser(this.state.token);
|
this.getGeneratedUser(this.state.inputToken);
|
||||||
this.setState({ loadingRobot: true, tokenHasChanged: false });
|
this.setState({ tokenHasChanged: false });
|
||||||
this.props.setAppState({
|
this.props.setRobot({
|
||||||
|
...this.props.robot,
|
||||||
avatarLoaded: false,
|
avatarLoaded: false,
|
||||||
nickname: null,
|
nickname: null,
|
||||||
token: null,
|
token: null,
|
||||||
@ -172,11 +170,11 @@ class UserGenPage extends Component {
|
|||||||
|
|
||||||
createJsonFile = () => {
|
createJsonFile = () => {
|
||||||
return {
|
return {
|
||||||
token: systemClient.getCookie('robot_token'),
|
token: this.props.robot.token,
|
||||||
token_shannon_entropy: this.state.shannon_entropy,
|
token_shannon_entropy: this.props.robot.shannonEntropy,
|
||||||
token_bit_entropy: this.state.bit_entropy,
|
token_bit_entropy: this.props.robot.bitsEntropy,
|
||||||
public_key: systemClient.getCookie('pub_key').split('\\').join('\n'),
|
public_key: this.props.robot.pub_key,
|
||||||
encrypted_private_key: systemClient.getCookie('enc_priv_key').split('\\').join('\n'),
|
encrypted_private_key: this.props.robot.enc_priv_key,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -195,12 +193,12 @@ class UserGenPage extends Component {
|
|||||||
align='center'
|
align='center'
|
||||||
sx={{ width: 370 * fontSizeFactor, height: 260 * fontSizeFactor }}
|
sx={{ width: 370 * fontSizeFactor, height: 260 * fontSizeFactor }}
|
||||||
>
|
>
|
||||||
{this.props.avatarLoaded && this.props.nickname ? (
|
{this.props.robot.avatarLoaded && this.props.robot.nickname ? (
|
||||||
<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>
|
<b>
|
||||||
{this.props.nickname && systemClient.getCookie('sessionid') ? (
|
{this.props.robot.nickname && systemClient.getCookie('sessionid') ? (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@ -217,7 +215,7 @@ class UserGenPage extends Component {
|
|||||||
width: 33 * fontSizeFactor,
|
width: 33 * fontSizeFactor,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<a>{this.props.nickname}</a>
|
<a>{this.props.robot.nickname}</a>
|
||||||
<BoltIcon
|
<BoltIcon
|
||||||
sx={{
|
sx={{
|
||||||
color: '#fcba03',
|
color: '#fcba03',
|
||||||
@ -234,7 +232,7 @@ class UserGenPage extends Component {
|
|||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} align='center'>
|
<Grid item xs={12} align='center'>
|
||||||
<RobotAvatar
|
<RobotAvatar
|
||||||
nickname={this.props.nickname}
|
nickname={this.props.robot.nickname}
|
||||||
smooth={true}
|
smooth={true}
|
||||||
style={{ maxWidth: 203 * fontSizeFactor, maxHeight: 203 * fontSizeFactor }}
|
style={{ maxWidth: 203 * fontSizeFactor, maxHeight: 203 * fontSizeFactor }}
|
||||||
imageStyle={{
|
imageStyle={{
|
||||||
@ -245,7 +243,7 @@ class UserGenPage extends Component {
|
|||||||
width: `${201 * fontSizeFactor}px`,
|
width: `${201 * fontSizeFactor}px`,
|
||||||
}}
|
}}
|
||||||
tooltip={t('This is your trading avatar')}
|
tooltip={t('This is your trading avatar')}
|
||||||
tooltipPosition='up'
|
tooltipPosition='top'
|
||||||
/>
|
/>
|
||||||
<br />
|
<br />
|
||||||
</Grid>
|
</Grid>
|
||||||
@ -271,7 +269,7 @@ class UserGenPage extends Component {
|
|||||||
error={!!this.state.bad_request}
|
error={!!this.state.bad_request}
|
||||||
label={t('Store your token safely')}
|
label={t('Store your token safely')}
|
||||||
required={true}
|
required={true}
|
||||||
value={this.state.token}
|
value={this.state.inputToken}
|
||||||
variant='standard'
|
variant='standard'
|
||||||
helperText={this.state.bad_request}
|
helperText={this.state.bad_request}
|
||||||
size='small'
|
size='small'
|
||||||
@ -301,11 +299,14 @@ class UserGenPage extends Component {
|
|||||||
<IconButton
|
<IconButton
|
||||||
color='primary'
|
color='primary'
|
||||||
disabled={
|
disabled={
|
||||||
!this.props.avatarLoaded ||
|
!this.props.robot.avatarLoaded ||
|
||||||
!(systemClient.getCookie('robot_token') === this.state.token)
|
!(systemClient.getCookie('robot_token') === this.state.inputToken)
|
||||||
}
|
}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
saveAsJson(this.props.nickname + '.json', this.createJsonFile())
|
saveAsJson(
|
||||||
|
this.props.robot.nickname + '.json',
|
||||||
|
this.createJsonFile(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<DownloadIcon
|
<DownloadIcon
|
||||||
@ -318,14 +319,14 @@ class UserGenPage extends Component {
|
|||||||
<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.robot.copiedToken ? 'inherit' : 'primary'}
|
||||||
disabled={
|
disabled={
|
||||||
!this.props.avatarLoaded ||
|
!this.props.robot.avatarLoaded ||
|
||||||
!(systemClient.getCookie('robot_token') === this.state.token)
|
!(systemClient.getCookie('robot_token') === this.state.inputToken)
|
||||||
}
|
}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
systemClient.copyToClipboard(systemClient.getCookie('robot_token')) &
|
systemClient.copyToClipboard(systemClient.getCookie('robot_token')) &
|
||||||
this.props.setAppState({ copiedToken: true })
|
this.props.setRobot({ ...this.props.robot, copiedToken: true })
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<ContentCopy
|
<ContentCopy
|
||||||
@ -376,9 +377,9 @@ class UserGenPage extends Component {
|
|||||||
<ButtonGroup variant='contained' aria-label='outlined primary button group'>
|
<ButtonGroup variant='contained' aria-label='outlined primary button group'>
|
||||||
<Button
|
<Button
|
||||||
disabled={
|
disabled={
|
||||||
this.state.loadingRobot !== false ||
|
this.props.robot.loading ||
|
||||||
!(this.props.token
|
!(this.props.robot.token
|
||||||
? systemClient.getCookie('robot_token') === this.props.token
|
? systemClient.getCookie('robot_token') === this.props.robot.token
|
||||||
: true)
|
: true)
|
||||||
}
|
}
|
||||||
color='primary'
|
color='primary'
|
||||||
@ -397,9 +398,9 @@ class UserGenPage extends Component {
|
|||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
disabled={
|
disabled={
|
||||||
this.state.loadingRobot !== false ||
|
this.props.robot.loading ||
|
||||||
!(this.props.token
|
!(this.props.robot.token
|
||||||
? systemClient.getCookie('robot_token') === this.props.token
|
? systemClient.getCookie('robot_token') === this.props.robot.token
|
||||||
: true)
|
: true)
|
||||||
}
|
}
|
||||||
color='secondary'
|
color='secondary'
|
||||||
@ -411,11 +412,11 @@ class UserGenPage extends Component {
|
|||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid item xs={12} align='center' sx={{ width: 370 * fontSizeFactor }}>
|
<Grid item xs={12} align='center' sx={{ width: '26.43em' }}>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<div style={{ height: 30 * fontSizeFactor }} />
|
<div style={{ height: '2.143em' }} />
|
||||||
</Grid>
|
</Grid>
|
||||||
<div style={{ width: 370 * fontSizeFactor, left: 30 * fontSizeFactor }}>
|
<div style={{ width: '26.43em', left: '2.143em' }}>
|
||||||
<Grid container align='center'>
|
<Grid container align='center'>
|
||||||
<Grid item xs={0.8} />
|
<Grid item xs={0.8} />
|
||||||
<Grid item xs={7.5} align='right'>
|
<Grid item xs={7.5} align='right'>
|
||||||
@ -424,10 +425,7 @@ class UserGenPage extends Component {
|
|||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={2.5} align='left'>
|
<Grid item xs={2.5} align='left'>
|
||||||
<RoboSatsNoTextIcon
|
<RoboSatsNoTextIcon color='primary' sx={{ height: '3.143em', width: '3.143em' }} />
|
||||||
color='primary'
|
|
||||||
sx={{ height: 72 * fontSizeFactor, width: 72 * fontSizeFactor }}
|
|
||||||
/>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</div>
|
</div>
|
||||||
|
@ -23,4 +23,9 @@ export interface Order {
|
|||||||
maker_status: 'Active' | 'Seen recently' | 'Inactive';
|
maker_status: 'Active' | 'Seen recently' | 'Inactive';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Book {
|
||||||
|
orders: Order[];
|
||||||
|
loading: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export default Order;
|
export default Order;
|
6
frontend/src/models/Favorites.model.ts
Normal file
6
frontend/src/models/Favorites.model.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export interface Favorites {
|
||||||
|
type: number | null;
|
||||||
|
currency: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Favorites;
|
49
frontend/src/models/Info.model.ts
Normal file
49
frontend/src/models/Info.model.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
export interface Info {
|
||||||
|
num_public_buy_orders: number;
|
||||||
|
num_public_sell_orders: number;
|
||||||
|
book_liquidity: number;
|
||||||
|
active_robots_today: number;
|
||||||
|
last_day_nonkyc_btc_premium: number;
|
||||||
|
last_day_volume: number;
|
||||||
|
lifetime_volume: number;
|
||||||
|
lnd_version: string;
|
||||||
|
robosats_running_commit_hash: string;
|
||||||
|
alternative_site: string;
|
||||||
|
alternative_name: string;
|
||||||
|
node_alias: string;
|
||||||
|
node_id: string;
|
||||||
|
version: { major: number | null; minor: number | null; patch: number | null };
|
||||||
|
maker_fee: number;
|
||||||
|
taker_fee: number;
|
||||||
|
bond_size: number;
|
||||||
|
current_swap_fee_rate: number;
|
||||||
|
coordinatorVersion: string;
|
||||||
|
clientVersion: string;
|
||||||
|
openUpdateClient: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const defaultInfo: Info = {
|
||||||
|
num_public_buy_orders: 0,
|
||||||
|
num_public_sell_orders: 0,
|
||||||
|
book_liquidity: 0,
|
||||||
|
active_robots_today: 0,
|
||||||
|
last_day_nonkyc_btc_premium: 0,
|
||||||
|
last_day_volume: 0,
|
||||||
|
lifetime_volume: 0,
|
||||||
|
lnd_version: 'v0.0.0-beta',
|
||||||
|
robosats_running_commit_hash: '000000000000000',
|
||||||
|
alternative_site: 'RoboSats6tkf3eva7x2voqso3a5wcorsnw34jveyxfqi2fu7oyheasid.onion',
|
||||||
|
alternative_name: 'RoboSats Mainnet',
|
||||||
|
node_alias: '🤖RoboSats⚡(RoboDevs)',
|
||||||
|
node_id: '033b58d7681fe5dd2fb21fd741996cda5449616f77317dd1156b80128d6a71b807',
|
||||||
|
version: { major: null, minor: null, patch: null },
|
||||||
|
maker_fee: 0,
|
||||||
|
taker_fee: 0,
|
||||||
|
bond_size: 0,
|
||||||
|
current_swap_fee_rate: 0,
|
||||||
|
coordinatorVersion: 'v?.?.?',
|
||||||
|
clientVersion: 'v?.?.?',
|
||||||
|
openUpdateClient: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Info;
|
@ -1,4 +1,5 @@
|
|||||||
export interface Maker {
|
export interface Maker {
|
||||||
|
advancedOptions: boolean;
|
||||||
isExplicit: boolean;
|
isExplicit: boolean;
|
||||||
amount: string;
|
amount: string;
|
||||||
paymentMethods: string[];
|
paymentMethods: string[];
|
||||||
@ -18,6 +19,7 @@ export interface Maker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const defaultMaker: Maker = {
|
export const defaultMaker: Maker = {
|
||||||
|
advancedOptions: false,
|
||||||
isExplicit: false,
|
isExplicit: false,
|
||||||
amount: '',
|
amount: '',
|
||||||
paymentMethods: [],
|
paymentMethods: [],
|
||||||
|
49
frontend/src/models/Robot.model.ts
Normal file
49
frontend/src/models/Robot.model.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import { systemClient } from '../services/System';
|
||||||
|
|
||||||
|
export interface Robot {
|
||||||
|
nickname: string | null;
|
||||||
|
token: string | null;
|
||||||
|
pub_key: string | null;
|
||||||
|
enc_priv_key: string | null;
|
||||||
|
bitsEntropy: number | null;
|
||||||
|
shannonEntropy: number | null;
|
||||||
|
stealthInvoices: boolean;
|
||||||
|
activeOrderId: number | null;
|
||||||
|
lastOrderId: number | null;
|
||||||
|
earnedRewards: number;
|
||||||
|
referralCode: string;
|
||||||
|
tgEnabled: boolean;
|
||||||
|
tgBotName: string;
|
||||||
|
tgToken: string;
|
||||||
|
loading: boolean;
|
||||||
|
avatarLoaded: boolean;
|
||||||
|
copiedToken: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const defaultRobot: Robot = {
|
||||||
|
nickname: null,
|
||||||
|
token: systemClient.getCookie('robot_token') ?? null,
|
||||||
|
pub_key:
|
||||||
|
systemClient.getCookie('pub_key') === undefined
|
||||||
|
? null
|
||||||
|
: systemClient.getCookie('pub_key').split('\\').join('\n'),
|
||||||
|
enc_priv_key:
|
||||||
|
systemClient.getCookie('enc_priv_key') === undefined
|
||||||
|
? null
|
||||||
|
: systemClient.getCookie('enc_priv_key').split('\\').join('\n'),
|
||||||
|
bitsEntropy: null,
|
||||||
|
shannonEntropy: null,
|
||||||
|
stealthInvoices: true,
|
||||||
|
activeOrderId: null,
|
||||||
|
lastOrderId: null,
|
||||||
|
earnedRewards: 0,
|
||||||
|
referralCode: '',
|
||||||
|
tgEnabled: false,
|
||||||
|
tgBotName: 'unknown',
|
||||||
|
tgToken: 'unknown',
|
||||||
|
loading: true,
|
||||||
|
avatarLoaded: false,
|
||||||
|
copiedToken: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Robot;
|
5
frontend/src/models/Settings.model.ts
Normal file
5
frontend/src/models/Settings.model.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export interface Settings {}
|
||||||
|
|
||||||
|
export const defaultSettings: Settings = {};
|
||||||
|
|
||||||
|
export default Settings;
|
@ -1,5 +1,14 @@
|
|||||||
export type { LimitList } from './Limit.model';
|
export type { LimitList } from './Limit.model';
|
||||||
export type { Limit } from './Limit.model';
|
export type { Limit } from './Limit.model';
|
||||||
export type { Maker } from './Maker.model';
|
export type { Maker } from './Maker.model';
|
||||||
|
export type { Order } from './Book.model';
|
||||||
|
export type { Book } from './Book.model';
|
||||||
|
export type { Robot } from './Robot.model';
|
||||||
|
export type { Info } from './Info.model';
|
||||||
|
export type { Settings } from './Settings.model';
|
||||||
|
export type { Favorites } from './Favorites.model';
|
||||||
|
|
||||||
export { defaultMaker } from './Maker.model';
|
export { defaultMaker } from './Maker.model';
|
||||||
export type { Order } from './Order.model';
|
export { defaultRobot } from './Robot.model';
|
||||||
|
export { defaultSettings } from './Settings.model';
|
||||||
|
export { defaultInfo } from './Info.model';
|
||||||
|
@ -11,8 +11,8 @@ export const checkVer: (
|
|||||||
return { updateAvailable: null };
|
return { updateAvailable: null };
|
||||||
}
|
}
|
||||||
const semver = packageJson.version.split('.');
|
const semver = packageJson.version.split('.');
|
||||||
const updateAvailable = major > Number(semver[0]) || minor > Number(semver[1]);
|
const updateAvailable: boolean = major > Number(semver[0]) || minor > Number(semver[1]);
|
||||||
const patchAvailable = !updateAvailable && patch > Number(semver[2]);
|
const patchAvailable: boolean = !updateAvailable && patch > Number(semver[2]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
updateAvailable,
|
updateAvailable,
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
import Order from '../models/Order.model';
|
import { Order, Favorites } from '../models';
|
||||||
|
|
||||||
interface BaseFilter {
|
|
||||||
currency: number;
|
|
||||||
type: number | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface AmountFilter {
|
interface AmountFilter {
|
||||||
amount: string;
|
amount: string;
|
||||||
@ -14,12 +9,12 @@ interface AmountFilter {
|
|||||||
|
|
||||||
interface FilterOrders {
|
interface FilterOrders {
|
||||||
orders: Order[];
|
orders: Order[];
|
||||||
baseFilter: BaseFilter;
|
baseFilter: Favorites;
|
||||||
amountFilter?: AmountFilter | null;
|
amountFilter?: AmountFilter | null;
|
||||||
paymentMethods?: string[];
|
paymentMethods?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const filterByPayment = function (order: Order, paymentMethods: string[]) {
|
const filterByPayment = function (order: Order, paymentMethods: any[]) {
|
||||||
if (paymentMethods.length === 0) {
|
if (paymentMethods.length === 0) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@ -32,17 +27,19 @@ const filterByPayment = function (order: Order, paymentMethods: string[]) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const filterByAmount = function (order: Order, filter: AmountFilter) {
|
const filterByAmount = function (order: Order, filter: AmountFilter) {
|
||||||
const filterMaxAmount = filter.amount != '' ? filter.amount : filter.maxAmount;
|
const filterMaxAmount =
|
||||||
const filterMinAmount = filter.amount != '' ? filter.amount : filter.minAmount;
|
Number(filter.amount != '' ? filter.amount : filter.maxAmount) * (1 + filter.threshold);
|
||||||
const orderMinAmount =
|
const filterMinAmount =
|
||||||
order.amount === '' || order.amount === null ? order.min_amount : order.amount;
|
Number(filter.amount != '' ? filter.amount : filter.minAmount) * (1 - filter.threshold);
|
||||||
const orderMaxAmount =
|
|
||||||
order.amount === '' || order.amount === null ? order.max_amount : order.amount;
|
|
||||||
|
|
||||||
return (
|
const orderMinAmount = Number(
|
||||||
orderMaxAmount < filterMaxAmount * (1 + filter.threshold) &&
|
order.amount === '' || order.amount === null ? order.min_amount : order.amount,
|
||||||
orderMinAmount > filterMinAmount * (1 - filter.threshold)
|
|
||||||
);
|
);
|
||||||
|
const orderMaxAmount = Number(
|
||||||
|
order.amount === '' || order.amount === null ? order.max_amount : order.amount,
|
||||||
|
);
|
||||||
|
|
||||||
|
return Math.max(filterMinAmount, orderMinAmount) <= Math.min(filterMaxAmount, orderMaxAmount);
|
||||||
};
|
};
|
||||||
|
|
||||||
const filterOrders = function ({
|
const filterOrders = function ({
|
||||||
@ -60,7 +57,6 @@ const filterOrders = function ({
|
|||||||
|
|
||||||
return typeChecks && currencyChecks && paymentMethodChecks && amountChecks;
|
return typeChecks && currencyChecks && paymentMethodChecks && amountChecks;
|
||||||
});
|
});
|
||||||
|
|
||||||
return filteredOrders;
|
return filteredOrders;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,11 +79,6 @@ input[type='number'] {
|
|||||||
-moz-appearance: textfield;
|
-moz-appearance: textfield;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bottomBar {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.amboss {
|
.amboss {
|
||||||
fill: url(#SVGID_1_);
|
fill: url(#SVGID_1_);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user