mirror of
https://github.com/RoboSats/robosats.git
synced 2025-01-31 10:31:35 +00:00
Add robot garage (#370)
* Add garage model * Add robot select to profile * Replace Robot for Garage init * Add Garage inners, not re-rendering * Revert * Collect new phrases and small fixes * Small fixes * Fix unencrypted # hack on Turtle chat * Small fixes and collect phrases
This commit is contained in:
parent
d88c2a5eff
commit
c0b8a6d3ac
@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useContext, useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Button, Grid, ButtonGroup, Dialog, Box } from '@mui/material';
|
import { Button, Grid, ButtonGroup, Dialog, Box } from '@mui/material';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
@ -7,49 +7,24 @@ import DepthChart from '../../components/Charts/DepthChart';
|
|||||||
import { NoRobotDialog } from '../../components/Dialogs';
|
import { NoRobotDialog } from '../../components/Dialogs';
|
||||||
import MakerForm from '../../components/MakerForm';
|
import MakerForm from '../../components/MakerForm';
|
||||||
import BookTable from '../../components/BookTable';
|
import BookTable from '../../components/BookTable';
|
||||||
import { Page } from '../NavBar';
|
|
||||||
import { Book, Favorites, LimitList, Maker } from '../../models';
|
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
import { BarChart, FormatListBulleted } from '@mui/icons-material';
|
import { BarChart, FormatListBulleted } from '@mui/icons-material';
|
||||||
|
import { AppContext, AppContextProps } from '../../contexts/AppContext';
|
||||||
|
|
||||||
interface BookPageProps {
|
const BookPage = (): JSX.Element => {
|
||||||
book: Book;
|
const {
|
||||||
limits: { list: LimitList; loading: boolean };
|
robot,
|
||||||
fetchLimits: () => void;
|
|
||||||
fav: Favorites;
|
|
||||||
setFav: (state: Favorites) => void;
|
|
||||||
onViewOrder: () => void;
|
|
||||||
fetchBook: () => void;
|
|
||||||
clearOrder: () => void;
|
|
||||||
windowSize: { width: number; height: number };
|
|
||||||
lastDayPremium: number;
|
|
||||||
maker: Maker;
|
|
||||||
setMaker: (state: Maker) => void;
|
|
||||||
hasRobot: boolean;
|
|
||||||
setPage: (state: Page) => void;
|
|
||||||
setCurrentOrder: (state: number) => void;
|
|
||||||
baseUrl: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const BookPage = ({
|
|
||||||
lastDayPremium = 0,
|
|
||||||
limits,
|
|
||||||
book = { orders: [], loading: true },
|
|
||||||
fetchBook,
|
fetchBook,
|
||||||
fetchLimits,
|
|
||||||
clearOrder,
|
clearOrder,
|
||||||
fav,
|
|
||||||
setFav,
|
|
||||||
onViewOrder,
|
|
||||||
maker,
|
|
||||||
setMaker,
|
|
||||||
windowSize,
|
windowSize,
|
||||||
hasRobot = false,
|
setPage,
|
||||||
setPage = () => null,
|
setCurrentOrder,
|
||||||
setCurrentOrder = () => null,
|
|
||||||
baseUrl,
|
baseUrl,
|
||||||
}: BookPageProps): JSX.Element => {
|
book,
|
||||||
|
setDelay,
|
||||||
|
setOrder,
|
||||||
|
} = useContext<AppContextProps>(AppContext);
|
||||||
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');
|
||||||
@ -62,15 +37,16 @@ const BookPage = ({
|
|||||||
const chartWidthEm = width - maxBookTableWidth;
|
const chartWidthEm = width - maxBookTableWidth;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (book.orders.length < 1) {
|
fetchBook();
|
||||||
fetchBook(true, false);
|
|
||||||
} else {
|
|
||||||
fetchBook(false, true);
|
|
||||||
}
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const onViewOrder = function () {
|
||||||
|
setOrder(undefined);
|
||||||
|
setDelay(10000);
|
||||||
|
};
|
||||||
|
|
||||||
const onOrderClicked = function (id: number) {
|
const onOrderClicked = function (id: number) {
|
||||||
if (hasRobot) {
|
if (robot.avatarLoaded) {
|
||||||
history.push('/order/' + id);
|
history.push('/order/' + id);
|
||||||
setPage('order');
|
setPage('order');
|
||||||
setCurrentOrder(id);
|
setCurrentOrder(id);
|
||||||
@ -108,6 +84,7 @@ const BookPage = ({
|
|||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid container direction='column' alignItems='center' spacing={1} sx={{ minWidth: 400 }}>
|
<Grid container direction='column' alignItems='center' spacing={1} sx={{ minWidth: 400 }}>
|
||||||
<NoRobotDialog open={openNoRobot} onClose={() => setOpenNoRobot(false)} setPage={setPage} />
|
<NoRobotDialog open={openNoRobot} onClose={() => setOpenNoRobot(false)} setPage={setPage} />
|
||||||
@ -115,21 +92,13 @@ const BookPage = ({
|
|||||||
<Dialog open={openMaker} onClose={() => setOpenMaker(false)}>
|
<Dialog open={openMaker} onClose={() => setOpenMaker(false)}>
|
||||||
<Box sx={{ maxWidth: '18em', padding: '0.5em' }}>
|
<Box sx={{ maxWidth: '18em', padding: '0.5em' }}>
|
||||||
<MakerForm
|
<MakerForm
|
||||||
limits={limits}
|
hasRobot={robot.AvatarLoaded}
|
||||||
fetchLimits={fetchLimits}
|
|
||||||
maker={maker}
|
|
||||||
setMaker={setMaker}
|
|
||||||
fav={fav}
|
|
||||||
setFav={setFav}
|
|
||||||
setPage={setPage}
|
|
||||||
hasRobot={hasRobot}
|
|
||||||
onOrderCreated={(id) => {
|
onOrderCreated={(id) => {
|
||||||
clearOrder();
|
clearOrder();
|
||||||
setCurrentOrder(id);
|
setCurrentOrder(id);
|
||||||
setPage('order');
|
setPage('order');
|
||||||
history.push('/order/' + id);
|
history.push('/order/' + id);
|
||||||
}}
|
}}
|
||||||
baseUrl={baseUrl}
|
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
@ -19,38 +19,18 @@ import { AppContextProps, AppContext } from '../contexts/AppContext';
|
|||||||
const Main = (): JSX.Element => {
|
const Main = (): JSX.Element => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const {
|
const {
|
||||||
book,
|
|
||||||
fetchBook,
|
|
||||||
maker,
|
|
||||||
setMaker,
|
|
||||||
clearOrder,
|
|
||||||
torStatus,
|
|
||||||
settings,
|
settings,
|
||||||
limits,
|
|
||||||
fetchLimits,
|
|
||||||
robot,
|
robot,
|
||||||
setRobot,
|
setRobot,
|
||||||
fetchRobot,
|
|
||||||
setOrder,
|
|
||||||
setDelay,
|
|
||||||
info,
|
|
||||||
fav,
|
|
||||||
setFav,
|
|
||||||
baseUrl,
|
baseUrl,
|
||||||
order,
|
order,
|
||||||
page,
|
page,
|
||||||
setPage,
|
setPage,
|
||||||
slideDirection,
|
slideDirection,
|
||||||
setSlideDirection,
|
|
||||||
currentOrder,
|
|
||||||
setCurrentOrder,
|
|
||||||
closeAll,
|
closeAll,
|
||||||
open,
|
|
||||||
setOpen,
|
setOpen,
|
||||||
windowSize,
|
windowSize,
|
||||||
badOrder,
|
|
||||||
navbarHeight,
|
navbarHeight,
|
||||||
setBadOrder,
|
|
||||||
} = useContext<AppContextProps>(AppContext);
|
} = useContext<AppContextProps>(AppContext);
|
||||||
|
|
||||||
const Router = window.NativeRobosats === undefined ? BrowserRouter : HashRouter;
|
const Router = window.NativeRobosats === undefined ? BrowserRouter : HashRouter;
|
||||||
@ -101,16 +81,7 @@ const Main = (): JSX.Element => {
|
|||||||
appear={slideDirection.in != undefined}
|
appear={slideDirection.in != undefined}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<RobotPage
|
<RobotPage />
|
||||||
setPage={setPage}
|
|
||||||
torStatus={torStatus}
|
|
||||||
fetchRobot={fetchRobot}
|
|
||||||
setCurrentOrder={setCurrentOrder}
|
|
||||||
windowSize={windowSize}
|
|
||||||
robot={robot}
|
|
||||||
setRobot={setRobot}
|
|
||||||
baseUrl={baseUrl}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</Slide>
|
</Slide>
|
||||||
)}
|
)}
|
||||||
@ -123,27 +94,7 @@ const Main = (): JSX.Element => {
|
|||||||
appear={slideDirection.in != undefined}
|
appear={slideDirection.in != undefined}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<BookPage
|
<BookPage />
|
||||||
book={book}
|
|
||||||
fetchBook={fetchBook}
|
|
||||||
onViewOrder={() => {
|
|
||||||
setOrder(undefined);
|
|
||||||
setDelay(10000);
|
|
||||||
}}
|
|
||||||
limits={limits}
|
|
||||||
fetchLimits={fetchLimits}
|
|
||||||
fav={fav}
|
|
||||||
setFav={setFav}
|
|
||||||
maker={maker}
|
|
||||||
setMaker={setMaker}
|
|
||||||
clearOrder={clearOrder}
|
|
||||||
lastDayPremium={info.last_day_nonkyc_btc_premium}
|
|
||||||
windowSize={windowSize}
|
|
||||||
hasRobot={robot.avatarLoaded}
|
|
||||||
setPage={setPage}
|
|
||||||
setCurrentOrder={setCurrentOrder}
|
|
||||||
baseUrl={baseUrl}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</Slide>
|
</Slide>
|
||||||
</Route>
|
</Route>
|
||||||
@ -155,7 +106,7 @@ const Main = (): JSX.Element => {
|
|||||||
appear={slideDirection.in != undefined}
|
appear={slideDirection.in != undefined}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<MakerPage hasRobot={robot.avatarLoaded} />
|
<MakerPage />
|
||||||
</div>
|
</div>
|
||||||
</Slide>
|
</Slide>
|
||||||
</Route>
|
</Route>
|
||||||
@ -169,10 +120,7 @@ const Main = (): JSX.Element => {
|
|||||||
appear={slideDirection.in != undefined}
|
appear={slideDirection.in != undefined}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<OrderPage
|
<OrderPage locationOrderId={props.match.params.orderId} />
|
||||||
locationOrderId={props.match.params.orderId}
|
|
||||||
hasRobot={robot.avatarLoaded}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</Slide>
|
</Slide>
|
||||||
)}
|
)}
|
||||||
@ -192,19 +140,9 @@ const Main = (): JSX.Element => {
|
|||||||
</Switch>
|
</Switch>
|
||||||
</Box>
|
</Box>
|
||||||
<div style={{ alignContent: 'center', display: 'flex' }}>
|
<div style={{ alignContent: 'center', display: 'flex' }}>
|
||||||
<NavBar width={windowSize.width} height={navbarHeight} hasRobot={robot.avatarLoaded} />
|
<NavBar width={windowSize.width} height={navbarHeight} />
|
||||||
</div>
|
</div>
|
||||||
<MainDialogs
|
<MainDialogs />
|
||||||
open={open}
|
|
||||||
setOpen={setOpen}
|
|
||||||
setRobot={setRobot}
|
|
||||||
setPage={setPage}
|
|
||||||
setCurrentOrder={setCurrentOrder}
|
|
||||||
info={info}
|
|
||||||
robot={robot}
|
|
||||||
closeAll={closeAll}
|
|
||||||
baseUrl={baseUrl}
|
|
||||||
/>
|
|
||||||
</Router>
|
</Router>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -10,13 +10,18 @@ import BookTable from '../../components/BookTable';
|
|||||||
|
|
||||||
import { AppContext, AppContextProps } from '../../contexts/AppContext';
|
import { AppContext, AppContextProps } from '../../contexts/AppContext';
|
||||||
|
|
||||||
interface MakerPageProps {
|
const MakerPage = (): JSX.Element => {
|
||||||
hasRobot: boolean;
|
const {
|
||||||
}
|
robot,
|
||||||
|
book,
|
||||||
const MakerPage = ({ hasRobot = false }: MakerPageProps): JSX.Element => {
|
fav,
|
||||||
const { book, fav, maker, clearOrder, windowSize, setCurrentOrder, navbarHeight, setPage } =
|
maker,
|
||||||
useContext<AppContextProps>(AppContext);
|
clearOrder,
|
||||||
|
windowSize,
|
||||||
|
setCurrentOrder,
|
||||||
|
navbarHeight,
|
||||||
|
setPage,
|
||||||
|
} = useContext<AppContextProps>(AppContext);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
@ -74,7 +79,7 @@ const MakerPage = ({ hasRobot = false }: MakerPageProps): JSX.Element => {
|
|||||||
setPage('order');
|
setPage('order');
|
||||||
history.push('/order/' + id);
|
history.push('/order/' + id);
|
||||||
}}
|
}}
|
||||||
hasRobot={hasRobot}
|
hasRobot={robot.avatarLoaded}
|
||||||
disableRequest={matches.length > 0 && !showMatches}
|
disableRequest={matches.length > 0 && !showMatches}
|
||||||
collapseAll={showMatches}
|
collapseAll={showMatches}
|
||||||
onSubmit={() => setShowMatches(matches.length > 0)}
|
onSubmit={() => setShowMatches(matches.length > 0)}
|
||||||
|
@ -20,17 +20,16 @@ import { AppContext, AppContextProps } from '../../contexts/AppContext';
|
|||||||
interface NavBarProps {
|
interface NavBarProps {
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
hasRobot: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const NavBar = ({ width, height, hasRobot = false }: NavBarProps): JSX.Element => {
|
const NavBar = ({ width, height }: NavBarProps): JSX.Element => {
|
||||||
const {
|
const {
|
||||||
|
robot,
|
||||||
page,
|
page,
|
||||||
settings,
|
settings,
|
||||||
setPage,
|
setPage,
|
||||||
setSlideDirection,
|
setSlideDirection,
|
||||||
open,
|
open,
|
||||||
robot,
|
|
||||||
setOpen,
|
setOpen,
|
||||||
closeAll,
|
closeAll,
|
||||||
currentOrder,
|
currentOrder,
|
||||||
@ -43,7 +42,7 @@ const NavBar = ({ width, height, hasRobot = false }: NavBarProps): JSX.Element =
|
|||||||
const smallBar = width < 50;
|
const smallBar = width < 50;
|
||||||
|
|
||||||
const tabSx = smallBar
|
const tabSx = smallBar
|
||||||
? { position: 'relative', bottom: robot.nickname ? '1em' : '0em', minWidth: '1em' }
|
? { position: 'relative', bottom: robot.avatarLoaded ? '0.9em' : '0.13em', minWidth: '1em' }
|
||||||
: { position: 'relative', bottom: '1em', minWidth: '2em' };
|
: { position: 'relative', bottom: '1em', minWidth: '2em' };
|
||||||
const pagesPosition = {
|
const pagesPosition = {
|
||||||
robot: 1,
|
robot: 1,
|
||||||
@ -137,7 +136,7 @@ const NavBar = ({ width, height, hasRobot = false }: NavBarProps): JSX.Element =
|
|||||||
sx={tabSx}
|
sx={tabSx}
|
||||||
label={smallBar ? undefined : t('Order')}
|
label={smallBar ? undefined : t('Order')}
|
||||||
value='order'
|
value='order'
|
||||||
disabled={!hasRobot || currentOrder == undefined}
|
disabled={!robot.avatarLoaded || currentOrder == undefined}
|
||||||
icon={<Assignment />}
|
icon={<Assignment />}
|
||||||
iconPosition='start'
|
iconPosition='start'
|
||||||
/>
|
/>
|
||||||
|
@ -6,20 +6,18 @@ import { useHistory } from 'react-router-dom';
|
|||||||
import TradeBox from '../../components/TradeBox';
|
import TradeBox from '../../components/TradeBox';
|
||||||
import OrderDetails from '../../components/OrderDetails';
|
import OrderDetails from '../../components/OrderDetails';
|
||||||
|
|
||||||
import { Page } from '../NavBar';
|
|
||||||
import { Order, Settings } from '../../models';
|
|
||||||
import { apiClient } from '../../services/api';
|
import { apiClient } from '../../services/api';
|
||||||
import { AppContext, AppContextProps } from '../../contexts/AppContext';
|
import { AppContext, AppContextProps } from '../../contexts/AppContext';
|
||||||
|
|
||||||
interface OrderPageProps {
|
interface OrderPageProps {
|
||||||
hasRobot: boolean;
|
|
||||||
locationOrderId: number;
|
locationOrderId: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const OrderPage = ({ hasRobot = false, locationOrderId }: OrderPageProps): JSX.Element => {
|
const OrderPage = ({ locationOrderId }: OrderPageProps): JSX.Element => {
|
||||||
const {
|
const {
|
||||||
windowSize,
|
windowSize,
|
||||||
order,
|
order,
|
||||||
|
robot,
|
||||||
settings,
|
settings,
|
||||||
setOrder,
|
setOrder,
|
||||||
setCurrentOrder,
|
setCurrentOrder,
|
||||||
@ -106,7 +104,7 @@ const OrderPage = ({ hasRobot = false, locationOrderId }: OrderPageProps): JSX.E
|
|||||||
setOrder={setOrder}
|
setOrder={setOrder}
|
||||||
baseUrl={baseUrl}
|
baseUrl={baseUrl}
|
||||||
setPage={setPage}
|
setPage={setPage}
|
||||||
hasRobot={hasRobot}
|
hasRobot={robot.avatarLoaded}
|
||||||
/>
|
/>
|
||||||
</Paper>
|
</Paper>
|
||||||
</Grid>
|
</Grid>
|
||||||
@ -121,6 +119,7 @@ const OrderPage = ({ hasRobot = false, locationOrderId }: OrderPageProps): JSX.E
|
|||||||
>
|
>
|
||||||
<TradeBox
|
<TradeBox
|
||||||
order={order}
|
order={order}
|
||||||
|
robot={robot}
|
||||||
settings={settings}
|
settings={settings}
|
||||||
setOrder={setOrder}
|
setOrder={setOrder}
|
||||||
setBadOrder={setBadOrder}
|
setBadOrder={setBadOrder}
|
||||||
@ -158,12 +157,13 @@ const OrderPage = ({ hasRobot = false, locationOrderId }: OrderPageProps): JSX.E
|
|||||||
setOrder={setOrder}
|
setOrder={setOrder}
|
||||||
baseUrl={baseUrl}
|
baseUrl={baseUrl}
|
||||||
setPage={setPage}
|
setPage={setPage}
|
||||||
hasRobot={hasRobot}
|
hasRobot={robot.avatarLoaded}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: tab == 'contract' ? '' : 'none' }}>
|
<div style={{ display: tab == 'contract' ? '' : 'none' }}>
|
||||||
<TradeBox
|
<TradeBox
|
||||||
order={order}
|
order={order}
|
||||||
|
robot={robot}
|
||||||
settings={settings}
|
settings={settings}
|
||||||
setOrder={setOrder}
|
setOrder={setOrder}
|
||||||
setBadOrder={setBadOrder}
|
setBadOrder={setBadOrder}
|
||||||
@ -189,7 +189,7 @@ const OrderPage = ({ hasRobot = false, locationOrderId }: OrderPageProps): JSX.E
|
|||||||
setOrder={setOrder}
|
setOrder={setOrder}
|
||||||
baseUrl={baseUrl}
|
baseUrl={baseUrl}
|
||||||
setPage={setPage}
|
setPage={setPage}
|
||||||
hasRobot={hasRobot}
|
hasRobot={robot.avatarLoaded}
|
||||||
/>
|
/>
|
||||||
</Paper>
|
</Paper>
|
||||||
)
|
)
|
||||||
|
@ -49,17 +49,16 @@ const Onboarding = ({
|
|||||||
}: OnboardingProps): JSX.Element => {
|
}: OnboardingProps): JSX.Element => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const theme = useTheme();
|
|
||||||
|
|
||||||
const [step, setStep] = useState<'1' | '2' | '3'>('1');
|
const [step, setStep] = useState<'1' | '2' | '3'>('1');
|
||||||
const [generatedToken, setGeneratedToken] = useState<boolean>(false);
|
const [generatedToken, setGeneratedToken] = useState<boolean>(false);
|
||||||
const [showMimickProgress, setShowMimickProgress] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
|
|
||||||
const generateToken = () => {
|
const generateToken = () => {
|
||||||
setGeneratedToken(true);
|
setGeneratedToken(true);
|
||||||
setInputToken(genBase62Token(36));
|
setInputToken(genBase62Token(36));
|
||||||
setShowMimickProgress(true);
|
setLoading(true);
|
||||||
setTimeout(() => setShowMimickProgress(false), 1000);
|
setTimeout(() => setLoading(false), 1000);
|
||||||
};
|
};
|
||||||
|
|
||||||
const changePage = function (newPage: Page) {
|
const changePage = function (newPage: Page) {
|
||||||
@ -104,10 +103,8 @@ const Onboarding = ({
|
|||||||
</Alert>
|
</Alert>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item sx={{ width: '100%' }}>
|
<Grid item sx={{ width: '100%' }}>
|
||||||
{showMimickProgress ? (
|
|
||||||
<LinearProgress sx={{ height: '0.7em' }} />
|
|
||||||
) : (
|
|
||||||
<TokenInput
|
<TokenInput
|
||||||
|
loading={loading}
|
||||||
autoFocusTarget='copyButton'
|
autoFocusTarget='copyButton'
|
||||||
inputToken={inputToken}
|
inputToken={inputToken}
|
||||||
setInputToken={setInputToken}
|
setInputToken={setInputToken}
|
||||||
@ -116,7 +113,6 @@ const Onboarding = ({
|
|||||||
robot={robot}
|
robot={robot}
|
||||||
onPressEnter={() => null}
|
onPressEnter={() => null}
|
||||||
/>
|
/>
|
||||||
)}
|
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Typography>
|
<Typography>
|
||||||
|
@ -1,22 +1,37 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState, useContext, useEffect } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import { Button, Link, Grid, LinearProgress, Typography, Alert } from '@mui/material';
|
import {
|
||||||
import { Bolt, Logout, Refresh } from '@mui/icons-material';
|
Button,
|
||||||
|
Grid,
|
||||||
|
LinearProgress,
|
||||||
|
Typography,
|
||||||
|
Alert,
|
||||||
|
Select,
|
||||||
|
MenuItem,
|
||||||
|
Box,
|
||||||
|
useTheme,
|
||||||
|
Tooltip,
|
||||||
|
} from '@mui/material';
|
||||||
|
import { Bolt, Add, DeleteSweep, Logout, Download } from '@mui/icons-material';
|
||||||
import RobotAvatar from '../../components/RobotAvatar';
|
import RobotAvatar from '../../components/RobotAvatar';
|
||||||
import TokenInput from './TokenInput';
|
import TokenInput from './TokenInput';
|
||||||
import { Page } from '../NavBar';
|
import { Page } from '../NavBar';
|
||||||
import { Robot } from '../../models';
|
import { Slot, Robot } from '../../models';
|
||||||
|
import { AppContext, AppContextProps } from '../../contexts/AppContext';
|
||||||
|
import { genBase62Token } from '../../utils';
|
||||||
|
import { LoadingButton } from '@mui/lab';
|
||||||
|
|
||||||
interface RobotProfileProps {
|
interface RobotProfileProps {
|
||||||
robot: Robot;
|
robot: Robot;
|
||||||
setRobot: (state: Robot) => void;
|
setRobot: (state: Robot) => void;
|
||||||
setView: (state: 'welcome' | 'onboarding' | 'recovery' | 'profile') => void;
|
setView: (state: 'welcome' | 'onboarding' | 'recovery' | 'profile') => void;
|
||||||
|
getGenerateRobot: (token: string, slot?: number) => void;
|
||||||
inputToken: string;
|
inputToken: string;
|
||||||
setCurrentOrder: (state: number) => void;
|
setCurrentOrder: (state: number) => void;
|
||||||
logoutRobot: () => void;
|
logoutRobot: () => void;
|
||||||
|
inputToken: string;
|
||||||
setInputToken: (state: string) => void;
|
setInputToken: (state: string) => void;
|
||||||
getGenerateRobot: (token: string) => void;
|
|
||||||
setPage: (state: Page) => void;
|
setPage: (state: Page) => void;
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
badRequest: string;
|
badRequest: string;
|
||||||
@ -27,9 +42,9 @@ const RobotProfile = ({
|
|||||||
robot,
|
robot,
|
||||||
setRobot,
|
setRobot,
|
||||||
inputToken,
|
inputToken,
|
||||||
|
getGenerateRobot,
|
||||||
setInputToken,
|
setInputToken,
|
||||||
setCurrentOrder,
|
setCurrentOrder,
|
||||||
getGenerateRobot,
|
|
||||||
logoutRobot,
|
logoutRobot,
|
||||||
setPage,
|
setPage,
|
||||||
setView,
|
setView,
|
||||||
@ -37,11 +52,41 @@ const RobotProfile = ({
|
|||||||
baseUrl,
|
baseUrl,
|
||||||
width,
|
width,
|
||||||
}: RobotProfileProps): JSX.Element => {
|
}: RobotProfileProps): JSX.Element => {
|
||||||
|
const { currentSlot, garage, setCurrentSlot, windowSize } =
|
||||||
|
useContext<AppContextProps>(AppContext);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const theme = useTheme();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (robot.nickname && robot.avatarLoaded) {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}, [robot]);
|
||||||
|
|
||||||
|
const handleAddRobot = () => {
|
||||||
|
getGenerateRobot(genBase62Token(36), garage.slots.length);
|
||||||
|
setLoading(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChangeSlot = (e) => {
|
||||||
|
const slot = e.target.value;
|
||||||
|
getGenerateRobot(garage.slots[slot].robot.token, slot);
|
||||||
|
setLoading(true);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid container direction='column' alignItems='center' spacing={2} padding={2}>
|
<Grid container direction='column' alignItems='center' spacing={1} padding={1} paddingTop={2}>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
container
|
||||||
|
direction='column'
|
||||||
|
alignItems='center'
|
||||||
|
spacing={1}
|
||||||
|
sx={{ width: '100%' }}
|
||||||
|
>
|
||||||
<Grid item sx={{ height: '2.3em', position: 'relative' }}>
|
<Grid item sx={{ height: '2.3em', position: 'relative' }}>
|
||||||
{robot.avatarLoaded && robot.nickname ? (
|
{robot.avatarLoaded && robot.nickname ? (
|
||||||
<Typography align='center' component='h5' variant='h5'>
|
<Typography align='center' component='h5' variant='h5'>
|
||||||
@ -99,17 +144,16 @@ const RobotProfile = ({
|
|||||||
tooltipPosition='top'
|
tooltipPosition='top'
|
||||||
baseUrl={baseUrl}
|
baseUrl={baseUrl}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
{robot.found && !robot.lastOrderId ? (
|
||||||
|
|
||||||
{robot.found ? (
|
|
||||||
<Typography align='center' variant='h6'>
|
<Typography align='center' variant='h6'>
|
||||||
{t('Welcome back!')}
|
{t('Welcome back!')}
|
||||||
</Typography>
|
</Typography>
|
||||||
) : (
|
) : (
|
||||||
<></>
|
<></>
|
||||||
)}
|
)}
|
||||||
|
</Grid>
|
||||||
|
|
||||||
{robot.activeOrderId ? (
|
{robot.activeOrderId && robot.avatarLoaded && robot.nickname ? (
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@ -123,7 +167,7 @@ const RobotProfile = ({
|
|||||||
</Grid>
|
</Grid>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{robot.lastOrderId ? (
|
{robot.lastOrderId && robot.avatarLoaded && robot.nickname ? (
|
||||||
<Grid item container direction='column' alignItems='center'>
|
<Grid item container direction='column' alignItems='center'>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Button
|
<Button
|
||||||
@ -145,16 +189,9 @@ const RobotProfile = ({
|
|||||||
)}
|
)}
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item sx={{ position: 'relative', right: '1em' }}>
|
<Grid item sx={{ position: 'relative', right: '1em' }}>
|
||||||
<Button
|
<Button color='success' size='small' onClick={handleAddRobot}>
|
||||||
color='inherit'
|
<Add />
|
||||||
size='small'
|
{t('Add a new Robot')}
|
||||||
onClick={() => {
|
|
||||||
logoutRobot();
|
|
||||||
setView('welcome');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Refresh />
|
|
||||||
{t('Generate a new Robot')}
|
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
@ -163,11 +200,37 @@ const RobotProfile = ({
|
|||||||
</Grid>
|
</Grid>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<Grid item sx={{ width: '100%' }}>
|
<Grid
|
||||||
|
item
|
||||||
|
container
|
||||||
|
direction='row'
|
||||||
|
justifyContent='stretch'
|
||||||
|
alignItems='stretch'
|
||||||
|
sx={{ width: '100%' }}
|
||||||
|
>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
xs={2}
|
||||||
|
sx={{ display: 'flex', justifyContent: 'stretch', alignItems: 'stretch' }}
|
||||||
|
>
|
||||||
|
<Tooltip enterTouchDelay={0} enterDelay={300} enterNextDelay={1000} title={t('Logout')}>
|
||||||
|
<Button
|
||||||
|
sx={{ minWidth: '2em', width: '100%' }}
|
||||||
|
color='primary'
|
||||||
|
variant='outlined'
|
||||||
|
onClick={() => {
|
||||||
|
logoutRobot();
|
||||||
|
setView('welcome');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Logout />
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={10}>
|
||||||
<TokenInput
|
<TokenInput
|
||||||
inputToken={inputToken}
|
inputToken={inputToken}
|
||||||
editable={false}
|
editable={false}
|
||||||
showDownload={true}
|
|
||||||
label={t('Store your token safely')}
|
label={t('Store your token safely')}
|
||||||
setInputToken={setInputToken}
|
setInputToken={setInputToken}
|
||||||
setRobot={setRobot}
|
setRobot={setRobot}
|
||||||
@ -176,21 +239,102 @@ const RobotProfile = ({
|
|||||||
onPressEnter={() => null}
|
onPressEnter={() => null}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
<Grid item sx={{ width: '100%' }}>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
backgroundColor: 'background.paper',
|
||||||
|
border: '1px solid',
|
||||||
|
borderRadius: '4px',
|
||||||
|
borderColor: theme.palette.mode === 'dark' ? '#434343' : '#c4c4c4',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Grid container direction='column' alignItems='center' spacing={2} padding={2}>
|
||||||
|
<Grid item sx={{ width: '100%' }}>
|
||||||
|
<Typography variant='caption'>{t('Robot Garage')}</Typography>
|
||||||
|
<Select
|
||||||
|
fullWidth
|
||||||
|
required={true}
|
||||||
|
inputProps={{
|
||||||
|
style: { textAlign: 'center' },
|
||||||
|
}}
|
||||||
|
value={loading ? 'loading' : currentSlot}
|
||||||
|
onChange={handleChangeSlot}
|
||||||
|
>
|
||||||
|
{loading ? (
|
||||||
|
<MenuItem key={'loading'} value={'loading'}>
|
||||||
|
<Typography>{t('Building...')}</Typography>
|
||||||
|
</MenuItem>
|
||||||
|
) : (
|
||||||
|
garage.slots.map((slot: Slot, index: number) => {
|
||||||
|
return (
|
||||||
|
<MenuItem key={index} value={index}>
|
||||||
|
<Grid
|
||||||
|
container
|
||||||
|
direction='row'
|
||||||
|
justifyContent='flex-start'
|
||||||
|
alignItems='center'
|
||||||
|
style={{ height: '2.8em' }}
|
||||||
|
spacing={1}
|
||||||
|
>
|
||||||
|
<Grid item>
|
||||||
|
<RobotAvatar
|
||||||
|
nickname={slot.robot.nickname}
|
||||||
|
smooth={true}
|
||||||
|
style={{ width: '2.6em', height: '2.6em' }}
|
||||||
|
placeholderType='loading'
|
||||||
|
baseUrl={baseUrl}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item>
|
||||||
|
<Typography variant={windowSize.width < 26 ? 'caption' : undefined}>
|
||||||
|
{slot.robot.nickname}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</MenuItem>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
)}
|
||||||
|
</Select>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid item container direction='row' alignItems='center' justifyContent='space-evenly'>
|
||||||
|
<Grid item>
|
||||||
|
<LoadingButton loading={loading} color='primary' onClick={handleAddRobot}>
|
||||||
|
<Add /> <div style={{ width: '0.5em' }} />
|
||||||
|
{t('Add Robot')}
|
||||||
|
</LoadingButton>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{window.NativeRobosats === undefined ? (
|
||||||
|
<Grid item>
|
||||||
|
<Button color='primary' onClick={() => garage.download()}>
|
||||||
|
<Download />
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
) : null}
|
||||||
|
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Button
|
<Button
|
||||||
size='small'
|
|
||||||
color='primary'
|
color='primary'
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
garage.delete();
|
||||||
|
setCurrentSlot(0);
|
||||||
logoutRobot();
|
logoutRobot();
|
||||||
setView('welcome');
|
setView('welcome');
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Logout /> <div style={{ width: '0.5em' }} />
|
<DeleteSweep /> <div style={{ width: '0.5em' }} />
|
||||||
{t('Logout Robot')}
|
{t('Delete Garage')}
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Box>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { IconButton, TextField, Tooltip, useTheme } from '@mui/material';
|
import { IconButton, LinearProgress, TextField, Tooltip } from '@mui/material';
|
||||||
import { Robot } from '../../models';
|
import { Robot } from '../../models';
|
||||||
import { Download, ContentCopy } from '@mui/icons-material';
|
import { ContentCopy } from '@mui/icons-material';
|
||||||
import { systemClient } from '../../services/System';
|
import { systemClient } from '../../services/System';
|
||||||
import { saveAsJson } from '../../utils';
|
|
||||||
|
|
||||||
interface TokenInputProps {
|
interface TokenInputProps {
|
||||||
robot: Robot;
|
robot: Robot;
|
||||||
editable?: boolean;
|
editable?: boolean;
|
||||||
showDownload?: boolean;
|
showDownload?: boolean;
|
||||||
fullWidth?: boolean;
|
fullWidth?: boolean;
|
||||||
|
loading?: boolean;
|
||||||
setRobot: (state: Robot) => void;
|
setRobot: (state: Robot) => void;
|
||||||
inputToken: string;
|
inputToken: string;
|
||||||
autoFocusTarget?: 'textfield' | 'copyButton' | 'none';
|
autoFocusTarget?: 'textfield' | 'copyButton' | 'none';
|
||||||
@ -27,12 +27,12 @@ const TokenInput = ({
|
|||||||
showCopy = true,
|
showCopy = true,
|
||||||
label,
|
label,
|
||||||
setRobot,
|
setRobot,
|
||||||
showDownload = false,
|
|
||||||
fullWidth = true,
|
fullWidth = true,
|
||||||
onPressEnter,
|
onPressEnter,
|
||||||
autoFocusTarget = 'textfield',
|
autoFocusTarget = 'textfield',
|
||||||
inputToken,
|
inputToken,
|
||||||
badRequest,
|
badRequest,
|
||||||
|
loading = false,
|
||||||
setInputToken,
|
setInputToken,
|
||||||
}: TokenInputProps): JSX.Element => {
|
}: TokenInputProps): JSX.Element => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -52,6 +52,9 @@ const TokenInput = ({
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return <LinearProgress sx={{ height: '0.8em' }} />;
|
||||||
|
} else {
|
||||||
return (
|
return (
|
||||||
<TextField
|
<TextField
|
||||||
error={!!badRequest}
|
error={!!badRequest}
|
||||||
@ -72,17 +75,6 @@ const TokenInput = ({
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
startAdornment: showDownload ? (
|
|
||||||
<Tooltip enterTouchDelay={250} title={t('Download token and PGP credentials')}>
|
|
||||||
<IconButton
|
|
||||||
color='primary'
|
|
||||||
sx={{ position: 'relative', top: label ? '0.4em' : '0em' }}
|
|
||||||
onClick={() => saveAsJson(robot.nickname + '.json', createJsonFile())}
|
|
||||||
>
|
|
||||||
<Download sx={{ width: '1em', height: '1em' }} />
|
|
||||||
</IconButton>
|
|
||||||
</Tooltip>
|
|
||||||
) : null,
|
|
||||||
endAdornment: showCopy ? (
|
endAdornment: showCopy ? (
|
||||||
<Tooltip open={showCopied} title={t('Copied!')}>
|
<Tooltip open={showCopied} title={t('Copied!')}>
|
||||||
<IconButton
|
<IconButton
|
||||||
@ -102,6 +94,7 @@ const TokenInput = ({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default TokenInput;
|
export default TokenInput;
|
||||||
|
@ -12,9 +12,7 @@ import {
|
|||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
|
|
||||||
import { Page } from '../NavBar';
|
|
||||||
import { Robot } from '../../models';
|
import { Robot } from '../../models';
|
||||||
import { systemClient } from '../../services/System';
|
|
||||||
import { apiClient } from '../../services/api';
|
import { apiClient } from '../../services/api';
|
||||||
import Onboarding from './Onboarding';
|
import Onboarding from './Onboarding';
|
||||||
import Welcome from './Welcome';
|
import Welcome from './Welcome';
|
||||||
@ -25,7 +23,7 @@ import { genKey } from '../../pgp';
|
|||||||
import { AppContext, AppContextProps } from '../../contexts/AppContext';
|
import { AppContext, AppContextProps } from '../../contexts/AppContext';
|
||||||
|
|
||||||
const RobotPage = (): JSX.Element => {
|
const RobotPage = (): JSX.Element => {
|
||||||
const { setPage, setCurrentOrder, fetchRobot, torStatus, windowSize, robot, setRobot, baseUrl } =
|
const { robot, setRobot, setPage, setCurrentOrder, fetchRobot, torStatus, windowSize, baseUrl } =
|
||||||
useContext<AppContextProps>(AppContext);
|
useContext<AppContextProps>(AppContext);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
@ -49,7 +47,7 @@ const RobotPage = (): JSX.Element => {
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const getGenerateRobot = (token: string) => {
|
const getGenerateRobot = (token: string, slot?: number) => {
|
||||||
setInputToken(token);
|
setInputToken(token);
|
||||||
genKey(token).then(function (key) {
|
genKey(token).then(function (key) {
|
||||||
fetchRobot({
|
fetchRobot({
|
||||||
@ -59,24 +57,16 @@ const RobotPage = (): JSX.Element => {
|
|||||||
encPrivKey: key.encryptedPrivateKeyArmored,
|
encPrivKey: key.encryptedPrivateKeyArmored,
|
||||||
},
|
},
|
||||||
newToken: token,
|
newToken: token,
|
||||||
|
slot,
|
||||||
refCode,
|
refCode,
|
||||||
setBadRequest,
|
setBadRequest,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteRobot = () => {
|
|
||||||
apiClient.delete(baseUrl, '/api/user');
|
|
||||||
logoutRobot();
|
|
||||||
};
|
|
||||||
|
|
||||||
const logoutRobot = () => {
|
const logoutRobot = () => {
|
||||||
setInputToken('');
|
setInputToken('');
|
||||||
systemClient.deleteCookie('sessionid');
|
setRobot(new Robot());
|
||||||
systemClient.deleteItem('robot_token');
|
|
||||||
systemClient.deleteItem('pub_key');
|
|
||||||
systemClient.deleteItem('enc_priv_key');
|
|
||||||
setTimeout(() => setRobot(new Robot()), 10);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!(window.NativeRobosats === undefined) && !(torStatus == 'DONE' || torStatus == '"Done"')) {
|
if (!(window.NativeRobosats === undefined) && !(torStatus == 'DONE' || torStatus == '"Done"')) {
|
||||||
@ -146,7 +136,7 @@ const RobotPage = (): JSX.Element => {
|
|||||||
<Onboarding
|
<Onboarding
|
||||||
setView={setView}
|
setView={setView}
|
||||||
robot={robot}
|
robot={robot}
|
||||||
setRobot={setRobot}
|
setRobot={() => null}
|
||||||
badRequest={badRequest}
|
badRequest={badRequest}
|
||||||
inputToken={inputToken}
|
inputToken={inputToken}
|
||||||
setInputToken={setInputToken}
|
setInputToken={setInputToken}
|
||||||
@ -160,9 +150,10 @@ const RobotPage = (): JSX.Element => {
|
|||||||
<RobotProfile
|
<RobotProfile
|
||||||
setView={setView}
|
setView={setView}
|
||||||
robot={robot}
|
robot={robot}
|
||||||
setRobot={setRobot}
|
setRobot={() => null}
|
||||||
setCurrentOrder={setCurrentOrder}
|
setCurrentOrder={setCurrentOrder}
|
||||||
badRequest={badRequest}
|
badRequest={badRequest}
|
||||||
|
getGenerateRobot={getGenerateRobot}
|
||||||
logoutRobot={logoutRobot}
|
logoutRobot={logoutRobot}
|
||||||
width={width}
|
width={width}
|
||||||
inputToken={inputToken}
|
inputToken={inputToken}
|
||||||
@ -177,7 +168,7 @@ const RobotPage = (): JSX.Element => {
|
|||||||
<Recovery
|
<Recovery
|
||||||
setView={setView}
|
setView={setView}
|
||||||
robot={robot}
|
robot={robot}
|
||||||
setRobot={setRobot}
|
setRobot={() => null}
|
||||||
badRequest={badRequest}
|
badRequest={badRequest}
|
||||||
inputToken={inputToken}
|
inputToken={inputToken}
|
||||||
setInputToken={setInputToken}
|
setInputToken={setInputToken}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React, { useContext } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
@ -14,6 +14,7 @@ import {
|
|||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { systemClient } from '../../services/System';
|
import { systemClient } from '../../services/System';
|
||||||
import ContentCopy from '@mui/icons-material/ContentCopy';
|
import ContentCopy from '@mui/icons-material/ContentCopy';
|
||||||
|
import { AppContext, AppContextProps } from '../../contexts/AppContext';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@ -23,6 +24,7 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const StoreTokenDialog = ({ open, onClose, onClickBack, onClickDone }: Props): JSX.Element => {
|
const StoreTokenDialog = ({ open, onClose, onClickBack, onClickDone }: Props): JSX.Element => {
|
||||||
|
const { robot } = useContext<AppContextProps>(AppContext);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -41,17 +43,13 @@ const StoreTokenDialog = ({ open, onClose, onClickBack, onClickDone }: Props): J
|
|||||||
sx={{ width: '100%', maxWidth: '550px' }}
|
sx={{ width: '100%', maxWidth: '550px' }}
|
||||||
disabled
|
disabled
|
||||||
label={t('Back it up!')}
|
label={t('Back it up!')}
|
||||||
value={systemClient.getItem('robot_token')}
|
value={robot.token}
|
||||||
variant='filled'
|
variant='filled'
|
||||||
size='small'
|
size='small'
|
||||||
InputProps={{
|
InputProps={{
|
||||||
endAdornment: (
|
endAdornment: (
|
||||||
<Tooltip disableHoverListener enterTouchDelay={0} title={t('Copied!')}>
|
<Tooltip disableHoverListener enterTouchDelay={0} title={t('Copied!')}>
|
||||||
<IconButton
|
<IconButton onClick={() => systemClient.copyToClipboard(robot.token)}>
|
||||||
onClick={() =>
|
|
||||||
systemClient.copyToClipboard(systemClient.getItem('robot_token'))
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<ContentCopy color='primary' />
|
<ContentCopy color='primary' />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
@ -40,6 +40,7 @@ const RobotAvatar: React.FC<Props> = ({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const [avatarSrc, setAvatarSrc] = useState<string>();
|
const [avatarSrc, setAvatarSrc] = useState<string>();
|
||||||
|
const [nicknameReady, setNicknameReady] = useState<boolean>(false);
|
||||||
|
|
||||||
const backgroundData =
|
const backgroundData =
|
||||||
placeholderType == 'generating' ? placeholder.generating : placeholder.loading;
|
placeholderType == 'generating' ? placeholder.generating : placeholder.loading;
|
||||||
@ -55,11 +56,15 @@ const RobotAvatar: React.FC<Props> = ({
|
|||||||
if (nickname != undefined) {
|
if (nickname != undefined) {
|
||||||
if (window.NativeRobosats === undefined) {
|
if (window.NativeRobosats === undefined) {
|
||||||
setAvatarSrc(baseUrl + '/static/assets/avatars/' + nickname + '.png');
|
setAvatarSrc(baseUrl + '/static/assets/avatars/' + nickname + '.png');
|
||||||
|
setNicknameReady(true);
|
||||||
} else {
|
} else {
|
||||||
|
setNicknameReady(true);
|
||||||
apiClient
|
apiClient
|
||||||
.fileImageUrl(baseUrl, '/static/assets/avatars/' + nickname + '.png')
|
.fileImageUrl(baseUrl, '/static/assets/avatars/' + nickname + '.png')
|
||||||
.then(setAvatarSrc);
|
.then(setAvatarSrc);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
setNicknameReady(false);
|
||||||
}
|
}
|
||||||
}, [nickname]);
|
}, [nickname]);
|
||||||
|
|
||||||
@ -93,7 +98,7 @@ const RobotAvatar: React.FC<Props> = ({
|
|||||||
>
|
>
|
||||||
<div className={className}>
|
<div className={className}>
|
||||||
<SmoothImage
|
<SmoothImage
|
||||||
src={avatarSrc}
|
src={nicknameReady ? avatarSrc : null}
|
||||||
imageStyles={{
|
imageStyles={{
|
||||||
borderRadius: '50%',
|
borderRadius: '50%',
|
||||||
border: '0.3px solid #55555',
|
border: '0.3px solid #55555',
|
||||||
@ -110,7 +115,7 @@ const RobotAvatar: React.FC<Props> = ({
|
|||||||
className={avatarClass}
|
className={avatarClass}
|
||||||
style={style}
|
style={style}
|
||||||
alt={nickname}
|
alt={nickname}
|
||||||
src={avatarSrc}
|
src={nicknameReady ? avatarSrc : null}
|
||||||
imgProps={{
|
imgProps={{
|
||||||
sx: { transform: flipHorizontally ? 'scaleX(-1)' : '' },
|
sx: { transform: flipHorizontally ? 'scaleX(-1)' : '' },
|
||||||
style: { transform: flipHorizontally ? 'scaleX(-1)' : '' },
|
style: { transform: flipHorizontally ? 'scaleX(-1)' : '' },
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Button, Tooltip, TextField, Grid, Container, Paper, Typography } from '@mui/material';
|
import { Button, Tooltip, TextField, Grid, Paper } from '@mui/material';
|
||||||
import { encryptMessage, decryptMessage } from '../../../../pgp';
|
import { encryptMessage, decryptMessage } from '../../../../pgp';
|
||||||
import { saveAsJson } from '../../../../utils';
|
|
||||||
import { AuditPGPDialog } from '../../../Dialogs';
|
import { AuditPGPDialog } from '../../../Dialogs';
|
||||||
import { systemClient } from '../../../../services/System';
|
|
||||||
import { websocketClient, WebsocketConnection } from '../../../../services/Websocket';
|
import { websocketClient, WebsocketConnection } from '../../../../services/Websocket';
|
||||||
|
import { Robot } from '../../../../models';
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
import CircularProgress from '@mui/material/CircularProgress';
|
import CircularProgress from '@mui/material/CircularProgress';
|
||||||
@ -19,6 +18,7 @@ import ChatBottom from '../ChatBottom';
|
|||||||
interface Props {
|
interface Props {
|
||||||
orderId: number;
|
orderId: number;
|
||||||
status: number;
|
status: number;
|
||||||
|
robot: Robot;
|
||||||
userNick: string;
|
userNick: string;
|
||||||
takerNick: string;
|
takerNick: string;
|
||||||
messages: EncryptedChatMessage[];
|
messages: EncryptedChatMessage[];
|
||||||
@ -31,6 +31,7 @@ interface Props {
|
|||||||
const EncryptedSocketChat: React.FC<Props> = ({
|
const EncryptedSocketChat: React.FC<Props> = ({
|
||||||
orderId,
|
orderId,
|
||||||
status,
|
status,
|
||||||
|
robot,
|
||||||
userNick,
|
userNick,
|
||||||
takerNick,
|
takerNick,
|
||||||
messages,
|
messages,
|
||||||
@ -45,14 +46,10 @@ const EncryptedSocketChat: React.FC<Props> = ({
|
|||||||
const audio = new Audio(`/static/assets/sounds/chat-open.mp3`);
|
const audio = new Audio(`/static/assets/sounds/chat-open.mp3`);
|
||||||
const [connected, setConnected] = useState<boolean>(false);
|
const [connected, setConnected] = useState<boolean>(false);
|
||||||
const [peerConnected, setPeerConnected] = useState<boolean>(false);
|
const [peerConnected, setPeerConnected] = useState<boolean>(false);
|
||||||
const [ownPubKey] = useState<string>(
|
const [ownPubKey] = useState<string>(robot.pubKey);
|
||||||
(systemClient.getItem('pub_key') ?? '').split('\\').join('\n'),
|
const [ownEncPrivKey] = useState<string>(robot.encPrivKey);
|
||||||
);
|
|
||||||
const [ownEncPrivKey] = useState<string>(
|
|
||||||
(systemClient.getItem('enc_priv_key') ?? '').split('\\').join('\n'),
|
|
||||||
);
|
|
||||||
const [peerPubKey, setPeerPubKey] = useState<string>();
|
const [peerPubKey, setPeerPubKey] = useState<string>();
|
||||||
const [token] = useState<string>(systemClient.getItem('robot_token') || '');
|
const [token] = useState<string>(robot.token);
|
||||||
const [serverMessages, setServerMessages] = useState<ServerMessage[]>([]);
|
const [serverMessages, setServerMessages] = useState<ServerMessage[]>([]);
|
||||||
const [value, setValue] = useState<string>('');
|
const [value, setValue] = useState<string>('');
|
||||||
const [connection, setConnection] = useState<WebsocketConnection>();
|
const [connection, setConnection] = useState<WebsocketConnection>();
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Button, TextField, Grid, Container, Paper } from '@mui/material';
|
import { Button, TextField, Grid, Paper } from '@mui/material';
|
||||||
import { encryptMessage, decryptMessage } from '../../../../pgp';
|
import { encryptMessage, decryptMessage } from '../../../../pgp';
|
||||||
import { AuditPGPDialog } from '../../../Dialogs';
|
import { AuditPGPDialog } from '../../../Dialogs';
|
||||||
import { systemClient } from '../../../../services/System';
|
import { Robot } from '../../../../models';
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
import CircularProgress from '@mui/material/CircularProgress';
|
import CircularProgress from '@mui/material/CircularProgress';
|
||||||
@ -17,6 +17,7 @@ import ChatBottom from '../ChatBottom';
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
orderId: number;
|
orderId: number;
|
||||||
|
robot: Robot;
|
||||||
userNick: string;
|
userNick: string;
|
||||||
takerNick: string;
|
takerNick: string;
|
||||||
chatOffset: number;
|
chatOffset: number;
|
||||||
@ -29,6 +30,7 @@ interface Props {
|
|||||||
|
|
||||||
const EncryptedTurtleChat: React.FC<Props> = ({
|
const EncryptedTurtleChat: React.FC<Props> = ({
|
||||||
orderId,
|
orderId,
|
||||||
|
robot,
|
||||||
userNick,
|
userNick,
|
||||||
takerNick,
|
takerNick,
|
||||||
chatOffset,
|
chatOffset,
|
||||||
@ -43,14 +45,10 @@ const EncryptedTurtleChat: React.FC<Props> = ({
|
|||||||
|
|
||||||
const audio = new Audio(`/static/assets/sounds/chat-open.mp3`);
|
const audio = new Audio(`/static/assets/sounds/chat-open.mp3`);
|
||||||
const [peerConnected, setPeerConnected] = useState<boolean>(false);
|
const [peerConnected, setPeerConnected] = useState<boolean>(false);
|
||||||
const [ownPubKey] = useState<string>(
|
const [ownPubKey] = useState<string>(robot.pubKey || '');
|
||||||
(systemClient.getItem('pub_key') ?? '').split('\\').join('\n'),
|
const [ownEncPrivKey] = useState<string>(robot.encPrivKey || '');
|
||||||
);
|
|
||||||
const [ownEncPrivKey] = useState<string>(
|
|
||||||
(systemClient.getItem('enc_priv_key') ?? '').split('\\').join('\n'),
|
|
||||||
);
|
|
||||||
const [peerPubKey, setPeerPubKey] = useState<string>();
|
const [peerPubKey, setPeerPubKey] = useState<string>();
|
||||||
const [token] = useState<string>(systemClient.getItem('robot_token') || '');
|
const [token] = useState<string>(robot.token || '');
|
||||||
const [value, setValue] = useState<string>('');
|
const [value, setValue] = useState<string>('');
|
||||||
const [audit, setAudit] = useState<boolean>(false);
|
const [audit, setAudit] = useState<boolean>(false);
|
||||||
const [waitingEcho, setWaitingEcho] = useState<boolean>(false);
|
const [waitingEcho, setWaitingEcho] = useState<boolean>(false);
|
||||||
@ -171,8 +169,9 @@ const EncryptedTurtleChat: React.FC<Props> = ({
|
|||||||
// If input string contains '#' send unencrypted and unlogged message
|
// If input string contains '#' send unencrypted and unlogged message
|
||||||
else if (value.substring(0, 1) == '#') {
|
else if (value.substring(0, 1) == '#') {
|
||||||
apiClient
|
apiClient
|
||||||
.post(baseUrl, `/api/chat`, {
|
.post(baseUrl, `/api/chat/`, {
|
||||||
PGP_message: value,
|
PGP_message: value,
|
||||||
|
order_id: orderId,
|
||||||
offset: lastIndex,
|
offset: lastIndex,
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
import { Robot } from '../../../models';
|
||||||
import EncryptedSocketChat from './EncryptedSocketChat';
|
import EncryptedSocketChat from './EncryptedSocketChat';
|
||||||
import EncryptedTurtleChat from './EncryptedTurtleChat';
|
import EncryptedTurtleChat from './EncryptedTurtleChat';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
orderId: number;
|
orderId: number;
|
||||||
|
status: number;
|
||||||
takerNick: string;
|
takerNick: string;
|
||||||
makerNick: string;
|
makerNick: string;
|
||||||
userNick: string;
|
userNick: string;
|
||||||
@ -15,6 +17,7 @@ interface Props {
|
|||||||
|
|
||||||
export interface EncryptedChatMessage {
|
export interface EncryptedChatMessage {
|
||||||
userNick: string;
|
userNick: string;
|
||||||
|
robot: Robot;
|
||||||
validSignature: boolean;
|
validSignature: boolean;
|
||||||
plainTextMessage: string;
|
plainTextMessage: string;
|
||||||
encryptedMessage: string;
|
encryptedMessage: string;
|
||||||
@ -32,17 +35,20 @@ export interface ServerMessage {
|
|||||||
const EncryptedChat: React.FC<Props> = ({
|
const EncryptedChat: React.FC<Props> = ({
|
||||||
orderId,
|
orderId,
|
||||||
takerNick,
|
takerNick,
|
||||||
|
robot,
|
||||||
userNick,
|
userNick,
|
||||||
chatOffset,
|
chatOffset,
|
||||||
baseUrl,
|
baseUrl,
|
||||||
setMessages,
|
setMessages,
|
||||||
messages,
|
messages,
|
||||||
|
status,
|
||||||
}: Props): JSX.Element => {
|
}: Props): JSX.Element => {
|
||||||
const [turtleMode, setTurtleMode] = useState<boolean>(window.ReactNativeWebView !== undefined);
|
const [turtleMode, setTurtleMode] = useState<boolean>(window.ReactNativeWebView !== undefined);
|
||||||
|
|
||||||
return turtleMode ? (
|
return turtleMode ? (
|
||||||
<EncryptedTurtleChat
|
<EncryptedTurtleChat
|
||||||
messages={messages}
|
messages={messages}
|
||||||
|
robot={robot}
|
||||||
setMessages={setMessages}
|
setMessages={setMessages}
|
||||||
orderId={orderId}
|
orderId={orderId}
|
||||||
takerNick={takerNick}
|
takerNick={takerNick}
|
||||||
@ -54,7 +60,9 @@ const EncryptedChat: React.FC<Props> = ({
|
|||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<EncryptedSocketChat
|
<EncryptedSocketChat
|
||||||
|
status={status}
|
||||||
messages={messages}
|
messages={messages}
|
||||||
|
robot={robot}
|
||||||
setMessages={setMessages}
|
setMessages={setMessages}
|
||||||
orderId={orderId}
|
orderId={orderId}
|
||||||
takerNick={takerNick}
|
takerNick={takerNick}
|
||||||
|
@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import { Grid, Typography, Tooltip, Collapse, IconButton } from '@mui/material';
|
import { Grid, Typography, Tooltip, Collapse, IconButton } from '@mui/material';
|
||||||
import currencies from '../../../../static/assets/currencies.json';
|
import currencies from '../../../../static/assets/currencies.json';
|
||||||
|
|
||||||
import { Order } from '../../../models';
|
import { Order, Robot } from '../../../models';
|
||||||
import { pn } from '../../../utils';
|
import { pn } from '../../../utils';
|
||||||
import EncryptedChat, { EncryptedChatMessage } from '../EncryptedChat';
|
import EncryptedChat, { EncryptedChatMessage } from '../EncryptedChat';
|
||||||
import Countdown, { zeroPad } from 'react-countdown';
|
import Countdown, { zeroPad } from 'react-countdown';
|
||||||
@ -11,6 +11,7 @@ import { LoadingButton } from '@mui/lab';
|
|||||||
|
|
||||||
interface ChatPromptProps {
|
interface ChatPromptProps {
|
||||||
order: Order;
|
order: Order;
|
||||||
|
robot: Robot;
|
||||||
onClickConfirmSent: () => void;
|
onClickConfirmSent: () => void;
|
||||||
loadingSent: boolean;
|
loadingSent: boolean;
|
||||||
onClickConfirmReceived: () => void;
|
onClickConfirmReceived: () => void;
|
||||||
@ -24,6 +25,7 @@ interface ChatPromptProps {
|
|||||||
|
|
||||||
export const ChatPrompt = ({
|
export const ChatPrompt = ({
|
||||||
order,
|
order,
|
||||||
|
robot,
|
||||||
onClickConfirmSent,
|
onClickConfirmSent,
|
||||||
onClickConfirmReceived,
|
onClickConfirmReceived,
|
||||||
loadingSent,
|
loadingSent,
|
||||||
@ -116,6 +118,7 @@ export const ChatPrompt = ({
|
|||||||
<Grid item>
|
<Grid item>
|
||||||
<EncryptedChat
|
<EncryptedChat
|
||||||
status={order.status}
|
status={order.status}
|
||||||
|
robot={robot}
|
||||||
chatOffset={order.chat_last_index}
|
chatOffset={order.chat_last_index}
|
||||||
orderId={order.id}
|
orderId={order.id}
|
||||||
takerNick={order.taker_nick}
|
takerNick={order.taker_nick}
|
||||||
|
@ -93,6 +93,7 @@ const closeAll: OpenDialogProps = {
|
|||||||
interface TradeBoxProps {
|
interface TradeBoxProps {
|
||||||
order: Order;
|
order: Order;
|
||||||
setOrder: (state: Order) => void;
|
setOrder: (state: Order) => void;
|
||||||
|
robot: Robot;
|
||||||
setBadOrder: (state: string | undefined) => void;
|
setBadOrder: (state: string | undefined) => void;
|
||||||
onRenewOrder: () => void;
|
onRenewOrder: () => void;
|
||||||
onStartAgain: () => void;
|
onStartAgain: () => void;
|
||||||
@ -103,6 +104,7 @@ interface TradeBoxProps {
|
|||||||
const TradeBox = ({
|
const TradeBox = ({
|
||||||
order,
|
order,
|
||||||
setOrder,
|
setOrder,
|
||||||
|
robot,
|
||||||
settings,
|
settings,
|
||||||
baseUrl,
|
baseUrl,
|
||||||
setBadOrder,
|
setBadOrder,
|
||||||
@ -230,7 +232,7 @@ const TradeBox = ({
|
|||||||
const submitStatement = function () {
|
const submitStatement = function () {
|
||||||
let statement = dispute.statement;
|
let statement = dispute.statement;
|
||||||
if (dispute.attachLogs) {
|
if (dispute.attachLogs) {
|
||||||
const payload = { statement, messages, token: systemClient.getItem('robot_token') };
|
const payload = { statement, messages, token: robot.token };
|
||||||
statement = JSON.stringify(payload, null, 2);
|
statement = JSON.stringify(payload, null, 2);
|
||||||
}
|
}
|
||||||
setLoadingButtons({ ...noLoadingButtons, submitStatement: true });
|
setLoadingButtons({ ...noLoadingButtons, submitStatement: true });
|
||||||
@ -461,6 +463,7 @@ const TradeBox = ({
|
|||||||
return (
|
return (
|
||||||
<ChatPrompt
|
<ChatPrompt
|
||||||
order={order}
|
order={order}
|
||||||
|
robot={robot}
|
||||||
onClickConfirmSent={confirmFiatSent}
|
onClickConfirmSent={confirmFiatSent}
|
||||||
onClickConfirmReceived={() => setOpen({ ...open, confirmFiatReceived: true })}
|
onClickConfirmReceived={() => setOpen({ ...open, confirmFiatReceived: true })}
|
||||||
loadingSent={loadingButtons.fiatSent}
|
loadingSent={loadingButtons.fiatSent}
|
||||||
|
@ -7,6 +7,7 @@ import {
|
|||||||
LimitList,
|
LimitList,
|
||||||
Maker,
|
Maker,
|
||||||
Robot,
|
Robot,
|
||||||
|
Garage,
|
||||||
Info,
|
Info,
|
||||||
Settings,
|
Settings,
|
||||||
Favorites,
|
Favorites,
|
||||||
@ -22,7 +23,6 @@ import { sha256 } from 'js-sha256';
|
|||||||
|
|
||||||
import defaultCoordinators from '../../static/federation.json';
|
import defaultCoordinators from '../../static/federation.json';
|
||||||
import { useTheme } from '@mui/material';
|
import { useTheme } from '@mui/material';
|
||||||
import { systemClient } from '../services/System';
|
|
||||||
|
|
||||||
const getWindowSize = function (fontSize: number) {
|
const getWindowSize = function (fontSize: number) {
|
||||||
// returns window size in EM units
|
// returns window size in EM units
|
||||||
@ -61,10 +61,11 @@ export interface SlideDirection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface fetchRobotProps {
|
export interface fetchRobotProps {
|
||||||
action?: 'login' | 'generate';
|
action?: 'login' | 'generate' | 'refresh';
|
||||||
newKeys?: { encPrivKey: string; pubKey: string } | null;
|
newKeys?: { encPrivKey: string; pubKey: string } | null;
|
||||||
newToken?: string | null;
|
newToken?: string | null;
|
||||||
refCode?: string | null;
|
refCode?: string | null;
|
||||||
|
slot?: number | null;
|
||||||
setBadRequest?: (state: string) => void;
|
setBadRequest?: (state: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,6 +79,10 @@ export interface AppContextProps {
|
|||||||
setSettings: (state: Settings) => void;
|
setSettings: (state: Settings) => void;
|
||||||
book: Book;
|
book: Book;
|
||||||
info: Info;
|
info: Info;
|
||||||
|
garage: Garage;
|
||||||
|
setGarage: (state: Garage) => void;
|
||||||
|
currentSlot: number;
|
||||||
|
setCurrentSlot: (state: number) => void;
|
||||||
setBook: (state: Book) => void;
|
setBook: (state: Book) => void;
|
||||||
fetchBook: () => void;
|
fetchBook: () => void;
|
||||||
limits: { list: LimitList; loading: boolean };
|
limits: { list: LimitList; loading: boolean };
|
||||||
@ -200,7 +205,13 @@ export const AppContextProvider = ({
|
|||||||
list: [],
|
list: [],
|
||||||
loading: true,
|
loading: true,
|
||||||
});
|
});
|
||||||
const [robot, setRobot] = useState<Robot>(new Robot());
|
const [garage, setGarage] = useState<Garage>(() => {
|
||||||
|
const initialState = { setGarage };
|
||||||
|
const newGarage = new Garage(initialState);
|
||||||
|
return newGarage;
|
||||||
|
});
|
||||||
|
const [currentSlot, setCurrentSlot] = useState<number>(garage.slots.length - 1);
|
||||||
|
const [robot, setRobot] = useState<Robot>(new Robot(garage.slots[currentSlot].robot));
|
||||||
const [maker, setMaker] = useState<Maker>(defaultMaker);
|
const [maker, setMaker] = useState<Maker>(defaultMaker);
|
||||||
const [info, setInfo] = useState<Info>(defaultInfo);
|
const [info, setInfo] = useState<Info>(defaultInfo);
|
||||||
const [coordinators, setCoordinators] = useState<Coordinator[]>(defaultCoordinators);
|
const [coordinators, setCoordinators] = useState<Coordinator[]>(defaultCoordinators);
|
||||||
@ -219,7 +230,6 @@ export const AppContextProvider = ({
|
|||||||
in: undefined,
|
in: undefined,
|
||||||
out: undefined,
|
out: undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
const [currentOrder, setCurrentOrder] = useState<number | undefined>(undefined);
|
const [currentOrder, setCurrentOrder] = useState<number | undefined>(undefined);
|
||||||
|
|
||||||
const navbarHeight = 2.5;
|
const navbarHeight = 2.5;
|
||||||
@ -239,6 +249,13 @@ export const AppContextProvider = ({
|
|||||||
getWindowSize(theme.typography.fontSize),
|
getWindowSize(theme.typography.fontSize),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener('torStatus', (event) => {
|
||||||
|
// UX improv: delay the "Conencted" status by 10 secs to avoid long waits for first requests
|
||||||
|
setTimeout(() => setTorStatus(event?.detail), event?.detail === '"Done"' ? 10000 : 0);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (typeof window !== undefined) {
|
if (typeof window !== undefined) {
|
||||||
window.addEventListener('resize', onResize);
|
window.addEventListener('resize', onResize);
|
||||||
@ -257,15 +274,18 @@ export const AppContextProvider = ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let host = '';
|
let host = '';
|
||||||
|
let protocol = '';
|
||||||
if (window.NativeRobosats === undefined) {
|
if (window.NativeRobosats === undefined) {
|
||||||
host = getHost();
|
host = getHost();
|
||||||
|
protocol = location.protocol;
|
||||||
} else {
|
} else {
|
||||||
|
protocol = 'http:';
|
||||||
host =
|
host =
|
||||||
settings.network === 'mainnet'
|
settings.network === 'mainnet'
|
||||||
? coordinators[0].mainnetOnion
|
? coordinators[0].mainnetOnion
|
||||||
: coordinators[0].testnetOnion;
|
: coordinators[0].testnetOnion;
|
||||||
}
|
}
|
||||||
setBaseUrl(`${location.protocol}//${host}`);
|
setBaseUrl(`${protocol}//${host}`);
|
||||||
}, [settings.network]);
|
}, [settings.network]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -371,14 +391,19 @@ export const AppContextProvider = ({
|
|||||||
newKeys = null,
|
newKeys = null,
|
||||||
newToken = null,
|
newToken = null,
|
||||||
refCode = null,
|
refCode = null,
|
||||||
|
slot = null,
|
||||||
setBadRequest = () => {},
|
setBadRequest = () => {},
|
||||||
}: fetchRobotProps) {
|
}: fetchRobotProps) {
|
||||||
setRobot({ ...robot, loading: true, avatarLoaded: false });
|
const oldRobot = robot;
|
||||||
|
const targetSlot = slot ?? currentSlot;
|
||||||
|
if (action != 'refresh') {
|
||||||
|
setRobot(new Robot());
|
||||||
|
}
|
||||||
setBadRequest('');
|
setBadRequest('');
|
||||||
|
|
||||||
let requestBody = {};
|
let requestBody = {};
|
||||||
if (action == 'login') {
|
if (action == 'login' || action == 'refresh') {
|
||||||
requestBody.token_sha256 = sha256(newToken ?? robot.token);
|
requestBody.token_sha256 = sha256(newToken ?? oldRobot.token);
|
||||||
} else if (action == 'generate' && newToken != null) {
|
} else if (action == 'generate' && newToken != null) {
|
||||||
const strength = tokenStrength(newToken);
|
const strength = tokenStrength(newToken);
|
||||||
requestBody.token_sha256 = sha256(newToken);
|
requestBody.token_sha256 = sha256(newToken);
|
||||||
@ -386,11 +411,12 @@ export const AppContextProvider = ({
|
|||||||
requestBody.counts = strength.counts;
|
requestBody.counts = strength.counts;
|
||||||
requestBody.length = newToken.length;
|
requestBody.length = newToken.length;
|
||||||
requestBody.ref_code = refCode;
|
requestBody.ref_code = refCode;
|
||||||
requestBody.public_key = newKeys.pubKey ?? robot.pubkey;
|
requestBody.public_key = newKeys.pubKey ?? oldRobot.pubkey;
|
||||||
requestBody.encrypted_private_key = newKeys.encPrivKey ?? robot.encPrivKey;
|
requestBody.encrypted_private_key = newKeys.encPrivKey ?? oldRobot.encPrivKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
apiClient.post(baseUrl, '/api/user/', requestBody).then((data: any) => {
|
apiClient.post(baseUrl, '/api/user/', requestBody).then((data: any) => {
|
||||||
|
let newRobot = robot;
|
||||||
setCurrentOrder(
|
setCurrentOrder(
|
||||||
data.active_order_id
|
data.active_order_id
|
||||||
? data.active_order_id
|
? data.active_order_id
|
||||||
@ -400,25 +426,25 @@ export const AppContextProvider = ({
|
|||||||
);
|
);
|
||||||
if (data.bad_request) {
|
if (data.bad_request) {
|
||||||
setBadRequest(data.bad_request);
|
setBadRequest(data.bad_request);
|
||||||
setRobot({
|
newRobot = {
|
||||||
...robot,
|
...oldRobot,
|
||||||
loading: false,
|
loading: false,
|
||||||
nickname: data.nickname ?? robot.nickname,
|
nickname: data.nickname ?? oldRobot.nickname,
|
||||||
activeOrderId: data.active_order_id ?? null,
|
activeOrderId: data.active_order_id ?? null,
|
||||||
referralCode: data.referral_code ?? robot.referralCode,
|
referralCode: data.referral_code ?? oldRobot.referralCode,
|
||||||
earnedRewards: data.earned_rewards ?? robot.earnedRewards,
|
earnedRewards: data.earned_rewards ?? oldRobot.earnedRewards,
|
||||||
lastOrderId: data.last_order_id ?? robot.lastOrderId,
|
lastOrderId: data.last_order_id ?? oldRobot.lastOrderId,
|
||||||
stealthInvoices: data.wants_stealth ?? robot.stealthInvoices,
|
stealthInvoices: data.wants_stealth ?? robot.stealthInvoices,
|
||||||
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,
|
||||||
found: false,
|
found: false,
|
||||||
});
|
};
|
||||||
} else {
|
} else {
|
||||||
setRobot({
|
newRobot = {
|
||||||
...robot,
|
...oldRobot,
|
||||||
nickname: data.nickname,
|
nickname: data.nickname,
|
||||||
token: newToken ?? robot.token,
|
token: newToken ?? oldRobot.token,
|
||||||
loading: false,
|
loading: false,
|
||||||
activeOrderId: data.active_order_id ?? null,
|
activeOrderId: data.active_order_id ?? null,
|
||||||
lastOrderId: data.last_order_id ?? null,
|
lastOrderId: data.last_order_id ?? null,
|
||||||
@ -433,11 +459,11 @@ export const AppContextProvider = ({
|
|||||||
shannonEntropy: data.token_shannon_entropy,
|
shannonEntropy: data.token_shannon_entropy,
|
||||||
pubKey: data.public_key,
|
pubKey: data.public_key,
|
||||||
encPrivKey: data.encrypted_private_key,
|
encPrivKey: data.encrypted_private_key,
|
||||||
copiedToken: data.found ? true : robot.copiedToken,
|
copiedToken: data.found ? true : false,
|
||||||
});
|
};
|
||||||
systemClient.setItem('robot_token', newToken ?? robot.token);
|
setRobot(newRobot);
|
||||||
systemClient.setItem('pub_key', data.public_key.split('\n').join('\\'));
|
garage.updateRobot(newRobot, targetSlot);
|
||||||
systemClient.setItem('enc_priv_key', data.encrypted_private_key.split('\n').join('\\'));
|
setCurrentSlot(targetSlot);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -445,9 +471,9 @@ export const AppContextProvider = ({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (baseUrl != '' && page != 'robot') {
|
if (baseUrl != '' && page != 'robot') {
|
||||||
if (open.profile || (robot.token && robot.nickname === null)) {
|
if (open.profile || (robot.token && robot.nickname === null)) {
|
||||||
fetchRobot({ action: 'login' }); // fetch existing robot
|
fetchRobot({ action: 'refresh' }); // refresh/update existing robot
|
||||||
} else if (robot.token && robot.encPrivKey && robot.pubKey) {
|
} else if (robot.token && robot.encPrivKey && robot.pubKey) {
|
||||||
fetchRobot({ action: 'login' }); // create new robot with existing token and keys (on network and coordinator change)
|
fetchRobot({ action: 'refresh' }); // create new robot with existing token and keys (on network and coordinator change)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [open.profile, baseUrl]);
|
}, [open.profile, baseUrl]);
|
||||||
@ -460,8 +486,11 @@ export const AppContextProvider = ({
|
|||||||
setSettings,
|
setSettings,
|
||||||
book,
|
book,
|
||||||
setBook,
|
setBook,
|
||||||
|
garage,
|
||||||
|
setGarage,
|
||||||
|
currentSlot,
|
||||||
|
setCurrentSlot,
|
||||||
fetchBook,
|
fetchBook,
|
||||||
fetchRobot,
|
|
||||||
limits,
|
limits,
|
||||||
info,
|
info,
|
||||||
setLimits,
|
setLimits,
|
||||||
@ -471,6 +500,7 @@ export const AppContextProvider = ({
|
|||||||
clearOrder,
|
clearOrder,
|
||||||
robot,
|
robot,
|
||||||
setRobot,
|
setRobot,
|
||||||
|
fetchRobot,
|
||||||
baseUrl,
|
baseUrl,
|
||||||
setBaseUrl,
|
setBaseUrl,
|
||||||
fav,
|
fav,
|
||||||
|
51
frontend/src/models/Garage.model.ts
Normal file
51
frontend/src/models/Garage.model.ts
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import { Robot, Order } from '.';
|
||||||
|
import { systemClient } from '../services/System';
|
||||||
|
import { saveAsJson } from '../utils';
|
||||||
|
export interface Slot {
|
||||||
|
robot: Robot;
|
||||||
|
order: Order | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const emptySlot: Slot = { robot: new Robot(), order: null };
|
||||||
|
|
||||||
|
class Garage {
|
||||||
|
constructor(initialState?: Garage) {
|
||||||
|
if (initialState?.slots === undefined && systemClient.getItem('garage') != '') {
|
||||||
|
this.slots = JSON.parse(systemClient.getItem('garage'));
|
||||||
|
console.log('Robot Garage was loaded from local storage');
|
||||||
|
} else {
|
||||||
|
this.slots = [emptySlot];
|
||||||
|
}
|
||||||
|
this.setGarage = initialState?.setGarage || (() => {});
|
||||||
|
}
|
||||||
|
slots: Slot[] = [emptySlot];
|
||||||
|
setGarage: (state: Garage) => void = () => {};
|
||||||
|
|
||||||
|
save = () => {
|
||||||
|
systemClient.setItem('garage', JSON.stringify(this.slots));
|
||||||
|
this.setGarage(new Garage(this));
|
||||||
|
};
|
||||||
|
|
||||||
|
delete = () => {
|
||||||
|
this.slots = [emptySlot];
|
||||||
|
systemClient.deleteItem('garage');
|
||||||
|
this.save();
|
||||||
|
};
|
||||||
|
|
||||||
|
updateRobot: (robot: Robot, index: number) => void = (robot, index) => {
|
||||||
|
this.slots[index] = { robot, order: null };
|
||||||
|
this.save();
|
||||||
|
};
|
||||||
|
|
||||||
|
download = () => {
|
||||||
|
saveAsJson(`robotGarage_${new Date().toISOString()}.json`, this.slots);
|
||||||
|
};
|
||||||
|
|
||||||
|
deleteSlot: (index?: number) => void = (index) => {
|
||||||
|
const targetSlot = index ?? this.slots.length - 1;
|
||||||
|
this.slots.splice(targetSlot, 1);
|
||||||
|
this.save();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Garage;
|
@ -1,10 +1,10 @@
|
|||||||
import { systemClient } from '../services/System';
|
|
||||||
|
|
||||||
class Robot {
|
class Robot {
|
||||||
constructor() {
|
constructor(garageRobot?: Robot) {
|
||||||
this.token = systemClient.getItem('robot_token') ?? undefined;
|
if (garageRobot) {
|
||||||
this.pubKey = systemClient.getItem('pub_key') ?? undefined;
|
this.token = garageRobot?.token ?? undefined;
|
||||||
this.encPrivKey = systemClient.getItem('enc_priv_key') ?? undefined;
|
this.pubKey = garageRobot?.pubKey ?? undefined;
|
||||||
|
this.encPrivKey = garageRobot?.encPrivKey ?? undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public nickname?: string;
|
public nickname?: string;
|
||||||
|
@ -39,7 +39,7 @@ class BaseSettings {
|
|||||||
: i18n.resolvedLanguage.substring(0, 2);
|
: i18n.resolvedLanguage.substring(0, 2);
|
||||||
|
|
||||||
const networkCookie = systemClient.getItem('settings_network');
|
const networkCookie = systemClient.getItem('settings_network');
|
||||||
this.network = networkCookie !== '' ? networkCookie : undefined;
|
this.network = networkCookie !== '' ? networkCookie : 'mainnet';
|
||||||
}
|
}
|
||||||
|
|
||||||
public frontend: 'basic' | 'pro' = 'basic';
|
public frontend: 'basic' | 'pro' = 'basic';
|
||||||
@ -47,7 +47,7 @@ class BaseSettings {
|
|||||||
public fontSize: number = 14;
|
public fontSize: number = 14;
|
||||||
public language?: Language;
|
public language?: Language;
|
||||||
public freezeViewports: boolean = false;
|
public freezeViewports: boolean = false;
|
||||||
public network: 'mainnet' | 'testnet' | undefined = undefined;
|
public network: 'mainnet' | 'testnet' = 'mainnet';
|
||||||
public coordinator: Coordinator | undefined = undefined;
|
public coordinator: Coordinator | undefined = undefined;
|
||||||
public host?: string;
|
public host?: string;
|
||||||
public unsafeClient: boolean = false;
|
public unsafeClient: boolean = false;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import Robot from './Robot.model';
|
import Robot from './Robot.model';
|
||||||
|
import Garage from './Garage.model';
|
||||||
import Settings from './Settings.default.basic';
|
import Settings from './Settings.default.basic';
|
||||||
export { Robot, Settings };
|
export { Robot, Garage, Settings };
|
||||||
|
|
||||||
export type { LimitList } from './Limit.model';
|
export type { LimitList } from './Limit.model';
|
||||||
export type { Limit } from './Limit.model';
|
export type { Limit } from './Limit.model';
|
||||||
@ -9,6 +10,7 @@ export type { Order } from './Order.model';
|
|||||||
export type { PublicOrder } from './Book.model';
|
export type { PublicOrder } from './Book.model';
|
||||||
export type { Book } from './Book.model';
|
export type { Book } from './Book.model';
|
||||||
export type { Info } from './Info.model';
|
export type { Info } from './Info.model';
|
||||||
|
export type { Slot } from './Garage.model';
|
||||||
export type { Language } from './Settings.model';
|
export type { Language } from './Settings.model';
|
||||||
export type { Favorites } from './Favorites.model';
|
export type { Favorites } from './Favorites.model';
|
||||||
export type { Coordinator } from './Coordinator.model';
|
export type { Coordinator } from './Coordinator.model';
|
||||||
|
@ -12,11 +12,14 @@
|
|||||||
"Active order #{{orderID}}": "Ordre activa #{{orderID}}",
|
"Active order #{{orderID}}": "Ordre activa #{{orderID}}",
|
||||||
"Last order #{{orderID}}": "Última ordre #{{orderID}}",
|
"Last order #{{orderID}}": "Última ordre #{{orderID}}",
|
||||||
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "La reutilització de la identitat de trading degrada la teva privadesa davant d'altres usuaris, coordinadors i observadors.",
|
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "La reutilització de la identitat de trading degrada la teva privadesa davant d'altres usuaris, coordinadors i observadors.",
|
||||||
"Generate a new Robot": "Generar un nou Robot",
|
"Add a new Robot": "Add a new Robot",
|
||||||
|
"Logout": "Logout",
|
||||||
"Store your token safely": "Guarda el teu token de manera segura",
|
"Store your token safely": "Guarda el teu token de manera segura",
|
||||||
"Logout Robot": "Tanca sessió Robot",
|
"Robot Garage": "Robot Garage",
|
||||||
|
"Building...": "Building...",
|
||||||
|
"Add Robot": "Add Robot",
|
||||||
|
"Delete Garage": "Delete Garage",
|
||||||
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
||||||
"Download token and PGP credentials": "Descarrega el token i les credencials PGP",
|
|
||||||
"Copied!": "Copiat!",
|
"Copied!": "Copiat!",
|
||||||
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
||||||
"1. Generate a token": "1. Genera un token",
|
"1. Generate a token": "1. Genera un token",
|
||||||
@ -144,7 +147,7 @@
|
|||||||
"Public sell orders": "Ordres de venta públiques",
|
"Public sell orders": "Ordres de venta públiques",
|
||||||
"Book liquidity": "Liquiditat en el llibre",
|
"Book liquidity": "Liquiditat en el llibre",
|
||||||
"Today active robots": "Robots actius avui",
|
"Today active robots": "Robots actius avui",
|
||||||
"24h non-KYC bitcoin premium": "Prima de bitcoin sense KYC en 24h",
|
"Last 24h mean premium": "Last 24h mean premium",
|
||||||
"Maker fee": "Comissió del creador",
|
"Maker fee": "Comissió del creador",
|
||||||
"Taker fee": "Comissió del prenedor",
|
"Taker fee": "Comissió del prenedor",
|
||||||
"Current onchain payout fee": "Cost actual de rebre onchain",
|
"Current onchain payout fee": "Cost actual de rebre onchain",
|
||||||
|
@ -12,11 +12,14 @@
|
|||||||
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
||||||
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
||||||
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
||||||
"Generate a new Robot": "Generate a new Robot",
|
"Add a new Robot": "Add a new Robot",
|
||||||
|
"Logout": "Logout",
|
||||||
"Store your token safely": "Ulož si svůj token bezpečně",
|
"Store your token safely": "Ulož si svůj token bezpečně",
|
||||||
"Logout Robot": "Logout Robot",
|
"Robot Garage": "Robot Garage",
|
||||||
|
"Building...": "Building...",
|
||||||
|
"Add Robot": "Add Robot",
|
||||||
|
"Delete Garage": "Delete Garage",
|
||||||
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
||||||
"Download token and PGP credentials": "Download token and PGP credentials",
|
|
||||||
"Copied!": "Zkopirováno!!",
|
"Copied!": "Zkopirováno!!",
|
||||||
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
||||||
"1. Generate a token": "1. Generate a token",
|
"1. Generate a token": "1. Generate a token",
|
||||||
@ -144,7 +147,7 @@
|
|||||||
"Public sell orders": "Veřejné prodejní nabídky",
|
"Public sell orders": "Veřejné prodejní nabídky",
|
||||||
"Book liquidity": "Dostupná likvidita",
|
"Book liquidity": "Dostupná likvidita",
|
||||||
"Today active robots": "Dnešní aktivní roboti",
|
"Today active robots": "Dnešní aktivní roboti",
|
||||||
"24h non-KYC bitcoin premium": "24h no-KYC bitcoin přirážka",
|
"Last 24h mean premium": "Last 24h mean premium",
|
||||||
"Maker fee": "Poplatek tvůrce",
|
"Maker fee": "Poplatek tvůrce",
|
||||||
"Taker fee": "Poplatek příjemce",
|
"Taker fee": "Poplatek příjemce",
|
||||||
"Current onchain payout fee": "Současný poplatek za vyplacení na onchain ",
|
"Current onchain payout fee": "Současný poplatek za vyplacení na onchain ",
|
||||||
|
@ -12,11 +12,14 @@
|
|||||||
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
||||||
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
||||||
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
||||||
"Generate a new Robot": "Generate a new Robot",
|
"Add a new Robot": "Add a new Robot",
|
||||||
|
"Logout": "Logout",
|
||||||
"Store your token safely": "Verwahre deinen Token sicher",
|
"Store your token safely": "Verwahre deinen Token sicher",
|
||||||
"Logout Robot": "Logout Robot",
|
"Robot Garage": "Robot Garage",
|
||||||
|
"Building...": "Building...",
|
||||||
|
"Add Robot": "Add Robot",
|
||||||
|
"Delete Garage": "Delete Garage",
|
||||||
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
||||||
"Download token and PGP credentials": "Download token and PGP credentials",
|
|
||||||
"Copied!": "Kopiert!",
|
"Copied!": "Kopiert!",
|
||||||
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
||||||
"1. Generate a token": "1. Generate a token",
|
"1. Generate a token": "1. Generate a token",
|
||||||
@ -144,7 +147,7 @@
|
|||||||
"Public sell orders": "Öffentliche Verkaufsangebote",
|
"Public sell orders": "Öffentliche Verkaufsangebote",
|
||||||
"Book liquidity": "Marktplatz-Liquidität",
|
"Book liquidity": "Marktplatz-Liquidität",
|
||||||
"Today active robots": "Heute aktive Roboter",
|
"Today active robots": "Heute aktive Roboter",
|
||||||
"24h non-KYC bitcoin premium": "24h non-KYC Bitcoin-Aufschlag",
|
"Last 24h mean premium": "Last 24h mean premium",
|
||||||
"Maker fee": "Makergebühr",
|
"Maker fee": "Makergebühr",
|
||||||
"Taker fee": "Takergebühr",
|
"Taker fee": "Takergebühr",
|
||||||
"Current onchain payout fee": "Current onchain payout fee",
|
"Current onchain payout fee": "Current onchain payout fee",
|
||||||
|
@ -12,11 +12,14 @@
|
|||||||
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
||||||
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
||||||
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
||||||
"Generate a new Robot": "Generate a new Robot",
|
"Add a new Robot": "Add a new Robot",
|
||||||
|
"Logout": "Logout",
|
||||||
"Store your token safely": "Store your token safely",
|
"Store your token safely": "Store your token safely",
|
||||||
"Logout Robot": "Logout Robot",
|
"Robot Garage": "Robot Garage",
|
||||||
|
"Building...": "Building...",
|
||||||
|
"Add Robot": "Add Robot",
|
||||||
|
"Delete Garage": "Delete Garage",
|
||||||
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
||||||
"Download token and PGP credentials": "Download token and PGP credentials",
|
|
||||||
"Copied!": "Copied!",
|
"Copied!": "Copied!",
|
||||||
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
||||||
"1. Generate a token": "1. Generate a token",
|
"1. Generate a token": "1. Generate a token",
|
||||||
@ -144,7 +147,7 @@
|
|||||||
"Public sell orders": "Public sell orders",
|
"Public sell orders": "Public sell orders",
|
||||||
"Book liquidity": "Book liquidity",
|
"Book liquidity": "Book liquidity",
|
||||||
"Today active robots": "Today active robots",
|
"Today active robots": "Today active robots",
|
||||||
"24h non-KYC bitcoin premium": "24h non-KYC bitcoin premium",
|
"Last 24h mean premium": "Last 24h mean premium",
|
||||||
"Maker fee": "Maker fee",
|
"Maker fee": "Maker fee",
|
||||||
"Taker fee": "Taker fee",
|
"Taker fee": "Taker fee",
|
||||||
"Current onchain payout fee": "Current onchain payout fee",
|
"Current onchain payout fee": "Current onchain payout fee",
|
||||||
|
@ -12,11 +12,14 @@
|
|||||||
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
||||||
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
||||||
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
||||||
"Generate a new Robot": "Generate a new Robot",
|
"Add a new Robot": "Add a new Robot",
|
||||||
|
"Logout": "Logout",
|
||||||
"Store your token safely": "Guarda tu token de forma segura",
|
"Store your token safely": "Guarda tu token de forma segura",
|
||||||
"Logout Robot": "Logout Robot",
|
"Robot Garage": "Robot Garage",
|
||||||
|
"Building...": "Building...",
|
||||||
|
"Add Robot": "Add Robot",
|
||||||
|
"Delete Garage": "Delete Garage",
|
||||||
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
||||||
"Download token and PGP credentials": "Download token and PGP credentials",
|
|
||||||
"Copied!": "¡Copiado!",
|
"Copied!": "¡Copiado!",
|
||||||
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
||||||
"1. Generate a token": "1. Generate a token",
|
"1. Generate a token": "1. Generate a token",
|
||||||
@ -144,7 +147,7 @@
|
|||||||
"Public sell orders": "Órdenes de venta públicas",
|
"Public sell orders": "Órdenes de venta públicas",
|
||||||
"Book liquidity": "Liquidez en el libro",
|
"Book liquidity": "Liquidez en el libro",
|
||||||
"Today active robots": "Robots activos hoy",
|
"Today active robots": "Robots activos hoy",
|
||||||
"24h non-KYC bitcoin premium": "Prima de bitcoin sin KYC en 24h",
|
"Last 24h mean premium": "Last 24h mean premium",
|
||||||
"Maker fee": "Comisión del creador",
|
"Maker fee": "Comisión del creador",
|
||||||
"Taker fee": "Comisión del tomador",
|
"Taker fee": "Comisión del tomador",
|
||||||
"Current onchain payout fee": "Coste actual de recibir onchain",
|
"Current onchain payout fee": "Coste actual de recibir onchain",
|
||||||
|
@ -12,11 +12,14 @@
|
|||||||
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
||||||
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
||||||
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
||||||
"Generate a new Robot": "Generate a new Robot",
|
"Add a new Robot": "Add a new Robot",
|
||||||
|
"Logout": "Logout",
|
||||||
"Store your token safely": "Gorde zure tokena era seguru batean",
|
"Store your token safely": "Gorde zure tokena era seguru batean",
|
||||||
"Logout Robot": "Logout Robot",
|
"Robot Garage": "Robot Garage",
|
||||||
|
"Building...": "Building...",
|
||||||
|
"Add Robot": "Add Robot",
|
||||||
|
"Delete Garage": "Delete Garage",
|
||||||
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
||||||
"Download token and PGP credentials": "Download token and PGP credentials",
|
|
||||||
"Copied!": "Kopiatuta!",
|
"Copied!": "Kopiatuta!",
|
||||||
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
||||||
"1. Generate a token": "1. Generate a token",
|
"1. Generate a token": "1. Generate a token",
|
||||||
@ -144,7 +147,7 @@
|
|||||||
"Public sell orders": "Salmenta eskaera publikoak",
|
"Public sell orders": "Salmenta eskaera publikoak",
|
||||||
"Book liquidity": "Liburuaren likidezia",
|
"Book liquidity": "Liburuaren likidezia",
|
||||||
"Today active robots": "Robot aktiboak gaur",
|
"Today active robots": "Robot aktiboak gaur",
|
||||||
"24h non-KYC bitcoin premium": "24 orduko ez-KYC prima",
|
"Last 24h mean premium": "Last 24h mean premium",
|
||||||
"Maker fee": "Egile kuota",
|
"Maker fee": "Egile kuota",
|
||||||
"Taker fee": "Hartzaile kuota",
|
"Taker fee": "Hartzaile kuota",
|
||||||
"Current onchain payout fee": "Oraingo onchain jasotze-kuota",
|
"Current onchain payout fee": "Oraingo onchain jasotze-kuota",
|
||||||
|
@ -12,11 +12,14 @@
|
|||||||
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
||||||
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
||||||
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
||||||
"Generate a new Robot": "Generate a new Robot",
|
"Add a new Robot": "Add a new Robot",
|
||||||
|
"Logout": "Logout",
|
||||||
"Store your token safely": "Stockez votre jeton en sécurité",
|
"Store your token safely": "Stockez votre jeton en sécurité",
|
||||||
"Logout Robot": "Logout Robot",
|
"Robot Garage": "Robot Garage",
|
||||||
|
"Building...": "Building...",
|
||||||
|
"Add Robot": "Add Robot",
|
||||||
|
"Delete Garage": "Delete Garage",
|
||||||
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
||||||
"Download token and PGP credentials": "Download token and PGP credentials",
|
|
||||||
"Copied!": "Copié!",
|
"Copied!": "Copié!",
|
||||||
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
||||||
"1. Generate a token": "1. Generate a token",
|
"1. Generate a token": "1. Generate a token",
|
||||||
@ -144,7 +147,7 @@
|
|||||||
"Public sell orders": "Ordres de vente publics",
|
"Public sell orders": "Ordres de vente publics",
|
||||||
"Book liquidity": "Liquidité du livre",
|
"Book liquidity": "Liquidité du livre",
|
||||||
"Today active robots": "Robots actifs aujourd'hui",
|
"Today active robots": "Robots actifs aujourd'hui",
|
||||||
"24h non-KYC bitcoin premium": "Prime bitcoin non-KYC 24h",
|
"Last 24h mean premium": "Last 24h mean premium",
|
||||||
"Maker fee": "Frais du createur",
|
"Maker fee": "Frais du createur",
|
||||||
"Taker fee": "Frais du preneur",
|
"Taker fee": "Frais du preneur",
|
||||||
"Current onchain payout fee": "Current onchain payout fee",
|
"Current onchain payout fee": "Current onchain payout fee",
|
||||||
|
@ -12,11 +12,14 @@
|
|||||||
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
||||||
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
||||||
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
||||||
"Generate a new Robot": "Generate a new Robot",
|
"Add a new Robot": "Add a new Robot",
|
||||||
|
"Logout": "Logout",
|
||||||
"Store your token safely": "Custodisci il tuo gettone in modo sicuro",
|
"Store your token safely": "Custodisci il tuo gettone in modo sicuro",
|
||||||
"Logout Robot": "Logout Robot",
|
"Robot Garage": "Robot Garage",
|
||||||
|
"Building...": "Building...",
|
||||||
|
"Add Robot": "Add Robot",
|
||||||
|
"Delete Garage": "Delete Garage",
|
||||||
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
||||||
"Download token and PGP credentials": "Download token and PGP credentials",
|
|
||||||
"Copied!": "Copiato!",
|
"Copied!": "Copiato!",
|
||||||
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
||||||
"1. Generate a token": "1. Generate a token",
|
"1. Generate a token": "1. Generate a token",
|
||||||
@ -144,7 +147,7 @@
|
|||||||
"Public sell orders": "Ordini di vendita pubblici",
|
"Public sell orders": "Ordini di vendita pubblici",
|
||||||
"Book liquidity": "Registro della liquidità",
|
"Book liquidity": "Registro della liquidità",
|
||||||
"Today active robots": "I Robottini attivi oggi",
|
"Today active robots": "I Robottini attivi oggi",
|
||||||
"24h non-KYC bitcoin premium": "Premio bitcoin non-KYC 24h",
|
"Last 24h mean premium": "Last 24h mean premium",
|
||||||
"Maker fee": "Commissione dell'offerente",
|
"Maker fee": "Commissione dell'offerente",
|
||||||
"Taker fee": "Commissione dell'acquirente",
|
"Taker fee": "Commissione dell'acquirente",
|
||||||
"Current onchain payout fee": "Current onchain payout fee",
|
"Current onchain payout fee": "Current onchain payout fee",
|
||||||
|
@ -12,11 +12,14 @@
|
|||||||
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
||||||
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
||||||
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
||||||
"Generate a new Robot": "Generate a new Robot",
|
"Add a new Robot": "Add a new Robot",
|
||||||
|
"Logout": "Logout",
|
||||||
"Store your token safely": "Przechowuj swój token bezpiecznie",
|
"Store your token safely": "Przechowuj swój token bezpiecznie",
|
||||||
"Logout Robot": "Logout Robot",
|
"Robot Garage": "Robot Garage",
|
||||||
|
"Building...": "Building...",
|
||||||
|
"Add Robot": "Add Robot",
|
||||||
|
"Delete Garage": "Delete Garage",
|
||||||
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
||||||
"Download token and PGP credentials": "Download token and PGP credentials",
|
|
||||||
"Copied!": "Skopiowane!",
|
"Copied!": "Skopiowane!",
|
||||||
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
||||||
"1. Generate a token": "1. Generate a token",
|
"1. Generate a token": "1. Generate a token",
|
||||||
@ -144,7 +147,7 @@
|
|||||||
"Public sell orders": "Zlecenia sprzedaży publicznej",
|
"Public sell orders": "Zlecenia sprzedaży publicznej",
|
||||||
"Book liquidity": "Płynność księgowa",
|
"Book liquidity": "Płynność księgowa",
|
||||||
"Today active robots": "Dziś aktywne roboty",
|
"Today active robots": "Dziś aktywne roboty",
|
||||||
"24h non-KYC bitcoin premium": "24h premia bitcoin non-KYC",
|
"Last 24h mean premium": "Last 24h mean premium",
|
||||||
"Maker fee": "Opłata producenta",
|
"Maker fee": "Opłata producenta",
|
||||||
"Taker fee": "Opłata takera",
|
"Taker fee": "Opłata takera",
|
||||||
"Current onchain payout fee": "Current onchain payout fee",
|
"Current onchain payout fee": "Current onchain payout fee",
|
||||||
|
@ -12,11 +12,14 @@
|
|||||||
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
||||||
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
||||||
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
||||||
"Generate a new Robot": "Generate a new Robot",
|
"Add a new Robot": "Add a new Robot",
|
||||||
|
"Logout": "Logout",
|
||||||
"Store your token safely": "Guarde seu token de forma segura",
|
"Store your token safely": "Guarde seu token de forma segura",
|
||||||
"Logout Robot": "Logout Robot",
|
"Robot Garage": "Robot Garage",
|
||||||
|
"Building...": "Building...",
|
||||||
|
"Add Robot": "Add Robot",
|
||||||
|
"Delete Garage": "Delete Garage",
|
||||||
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
||||||
"Download token and PGP credentials": "Download token and PGP credentials",
|
|
||||||
"Copied!": "Copiado!",
|
"Copied!": "Copiado!",
|
||||||
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
||||||
"1. Generate a token": "1. Generate a token",
|
"1. Generate a token": "1. Generate a token",
|
||||||
@ -144,7 +147,7 @@
|
|||||||
"Public sell orders": "Ordens de venda públicss",
|
"Public sell orders": "Ordens de venda públicss",
|
||||||
"Book liquidity": "Liquidez do livro",
|
"Book liquidity": "Liquidez do livro",
|
||||||
"Today active robots": "Robôs ativos hoje",
|
"Today active robots": "Robôs ativos hoje",
|
||||||
"24h non-KYC bitcoin premium": "Prêmio de bitcoin não-KYC nas últimas 24 horas",
|
"Last 24h mean premium": "Last 24h mean premium",
|
||||||
"Maker fee": "Taxa do criador",
|
"Maker fee": "Taxa do criador",
|
||||||
"Taker fee": "Taxa do tomador",
|
"Taker fee": "Taxa do tomador",
|
||||||
"Current onchain payout fee": "Taxa de pagamento onchain atual",
|
"Current onchain payout fee": "Taxa de pagamento onchain atual",
|
||||||
|
@ -12,11 +12,14 @@
|
|||||||
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
||||||
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
||||||
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
||||||
"Generate a new Robot": "Generate a new Robot",
|
"Add a new Robot": "Add a new Robot",
|
||||||
|
"Logout": "Logout",
|
||||||
"Store your token safely": "Храните Ваш токен в безопасности",
|
"Store your token safely": "Храните Ваш токен в безопасности",
|
||||||
"Logout Robot": "Logout Robot",
|
"Robot Garage": "Robot Garage",
|
||||||
|
"Building...": "Building...",
|
||||||
|
"Add Robot": "Add Robot",
|
||||||
|
"Delete Garage": "Delete Garage",
|
||||||
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
||||||
"Download token and PGP credentials": "Download token and PGP credentials",
|
|
||||||
"Copied!": "Скопировано!",
|
"Copied!": "Скопировано!",
|
||||||
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
||||||
"1. Generate a token": "1. Generate a token",
|
"1. Generate a token": "1. Generate a token",
|
||||||
@ -144,7 +147,7 @@
|
|||||||
"Public sell orders": "Ордера на продажу",
|
"Public sell orders": "Ордера на продажу",
|
||||||
"Book liquidity": "Ликвидность книги ордеров",
|
"Book liquidity": "Ликвидность книги ордеров",
|
||||||
"Today active robots": "Сегодня активных роботов",
|
"Today active robots": "Сегодня активных роботов",
|
||||||
"24h non-KYC bitcoin premium": "Наценка на Биткойн без ЗСК за 24 часа",
|
"Last 24h mean premium": "Last 24h mean premium",
|
||||||
"Maker fee": "Комиссия мейкера",
|
"Maker fee": "Комиссия мейкера",
|
||||||
"Taker fee": "Комиссия тейкера",
|
"Taker fee": "Комиссия тейкера",
|
||||||
"Current onchain payout fee": "Текущая комиссия за выплату ончейн",
|
"Current onchain payout fee": "Текущая комиссия за выплату ончейн",
|
||||||
|
@ -12,11 +12,14 @@
|
|||||||
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
||||||
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
||||||
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
||||||
"Generate a new Robot": "Generate a new Robot",
|
"Add a new Robot": "Add a new Robot",
|
||||||
|
"Logout": "Logout",
|
||||||
"Store your token safely": "Spara din token säkert",
|
"Store your token safely": "Spara din token säkert",
|
||||||
"Logout Robot": "Logout Robot",
|
"Robot Garage": "Robot Garage",
|
||||||
|
"Building...": "Building...",
|
||||||
|
"Add Robot": "Add Robot",
|
||||||
|
"Delete Garage": "Delete Garage",
|
||||||
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
||||||
"Download token and PGP credentials": "Download token and PGP credentials",
|
|
||||||
"Copied!": "Kopierat!",
|
"Copied!": "Kopierat!",
|
||||||
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
||||||
"1. Generate a token": "1. Generate a token",
|
"1. Generate a token": "1. Generate a token",
|
||||||
@ -144,7 +147,7 @@
|
|||||||
"Public sell orders": "Publika säljordrar",
|
"Public sell orders": "Publika säljordrar",
|
||||||
"Book liquidity": "Orderbokslikviditet",
|
"Book liquidity": "Orderbokslikviditet",
|
||||||
"Today active robots": "Aktiva robotar idag",
|
"Today active robots": "Aktiva robotar idag",
|
||||||
"24h non-KYC bitcoin premium": "24h non-KYC bitcoin premium",
|
"Last 24h mean premium": "Last 24h mean premium",
|
||||||
"Maker fee": "Makeravgift",
|
"Maker fee": "Makeravgift",
|
||||||
"Taker fee": "Takeravgift",
|
"Taker fee": "Takeravgift",
|
||||||
"Current onchain payout fee": "Aktuell utbetalningsavgift (on-chain)",
|
"Current onchain payout fee": "Aktuell utbetalningsavgift (on-chain)",
|
||||||
|
@ -12,11 +12,14 @@
|
|||||||
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
||||||
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
||||||
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
||||||
"Generate a new Robot": "Generate a new Robot",
|
"Add a new Robot": "Add a new Robot",
|
||||||
|
"Logout": "Logout",
|
||||||
"Store your token safely": "รักษา token ของคุณไว้ให้ดี",
|
"Store your token safely": "รักษา token ของคุณไว้ให้ดี",
|
||||||
"Logout Robot": "Logout Robot",
|
"Robot Garage": "Robot Garage",
|
||||||
|
"Building...": "Building...",
|
||||||
|
"Add Robot": "Add Robot",
|
||||||
|
"Delete Garage": "Delete Garage",
|
||||||
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
||||||
"Download token and PGP credentials": "Download token and PGP credentials",
|
|
||||||
"Copied!": "คัดลอกแล้ว!",
|
"Copied!": "คัดลอกแล้ว!",
|
||||||
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
||||||
"1. Generate a token": "1. Generate a token",
|
"1. Generate a token": "1. Generate a token",
|
||||||
@ -144,7 +147,7 @@
|
|||||||
"Public sell orders": "จำนวนรายการขาย",
|
"Public sell orders": "จำนวนรายการขาย",
|
||||||
"Book liquidity": "สภาพคล่องทางบ้ญชี",
|
"Book liquidity": "สภาพคล่องทางบ้ญชี",
|
||||||
"Today active robots": "จำนวนโรบอทที่ใช้งานในวันนี้",
|
"Today active robots": "จำนวนโรบอทที่ใช้งานในวันนี้",
|
||||||
"24h non-KYC bitcoin premium": "ค่าพรีเมี่ยม 24 ชม.ที่แล้วสำหรับ bitcoin non-KYC",
|
"Last 24h mean premium": "Last 24h mean premium",
|
||||||
"Maker fee": "ค่าธรรมเนียม Maker",
|
"Maker fee": "ค่าธรรมเนียม Maker",
|
||||||
"Taker fee": "ค่าธรรมเนียม Taker",
|
"Taker fee": "ค่าธรรมเนียม Taker",
|
||||||
"Current onchain payout fee": "ค่าธรรมเนียมการจ่าย On-chain ตอนนี้",
|
"Current onchain payout fee": "ค่าธรรมเนียมการจ่าย On-chain ตอนนี้",
|
||||||
|
@ -12,11 +12,14 @@
|
|||||||
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
||||||
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
||||||
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
||||||
"Generate a new Robot": "Generate a new Robot",
|
"Add a new Robot": "Add a new Robot",
|
||||||
|
"Logout": "Logout",
|
||||||
"Store your token safely": "请安全地存储你的令牌",
|
"Store your token safely": "请安全地存储你的令牌",
|
||||||
"Logout Robot": "Logout Robot",
|
"Robot Garage": "Robot Garage",
|
||||||
|
"Building...": "Building...",
|
||||||
|
"Add Robot": "Add Robot",
|
||||||
|
"Delete Garage": "Delete Garage",
|
||||||
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
||||||
"Download token and PGP credentials": "Download token and PGP credentials",
|
|
||||||
"Copied!": "已复制!",
|
"Copied!": "已复制!",
|
||||||
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
||||||
"1. Generate a token": "1. Generate a token",
|
"1. Generate a token": "1. Generate a token",
|
||||||
@ -144,7 +147,7 @@
|
|||||||
"Public sell orders": "公开出售订单",
|
"Public sell orders": "公开出售订单",
|
||||||
"Book liquidity": "账面流动性",
|
"Book liquidity": "账面流动性",
|
||||||
"Today active robots": "今天活跃的机器人",
|
"Today active robots": "今天活跃的机器人",
|
||||||
"24h non-KYC bitcoin premium": "24小时 non-KYC 比特币溢价",
|
"Last 24h mean premium": "Last 24h mean premium",
|
||||||
"Maker fee": "挂单方费用",
|
"Maker fee": "挂单方费用",
|
||||||
"Taker fee": "吃单方费用",
|
"Taker fee": "吃单方费用",
|
||||||
"Current onchain payout fee": "当前链上支付费用",
|
"Current onchain payout fee": "当前链上支付费用",
|
||||||
|
@ -12,11 +12,14 @@
|
|||||||
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
"Active order #{{orderID}}": "Active order #{{orderID}}",
|
||||||
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
"Last order #{{orderID}}": "Last order #{{orderID}}",
|
||||||
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
"Reusing trading identity degrades your privacy against other users, coordinators and observers.": "Reusing trading identity degrades your privacy against other users, coordinators and observers.",
|
||||||
"Generate a new Robot": "Generate a new Robot",
|
"Add a new Robot": "Add a new Robot",
|
||||||
|
"Logout": "Logout",
|
||||||
"Store your token safely": "請安全地存儲你的令牌",
|
"Store your token safely": "請安全地存儲你的令牌",
|
||||||
"Logout Robot": "Logout Robot",
|
"Robot Garage": "Robot Garage",
|
||||||
|
"Building...": "Building...",
|
||||||
|
"Add Robot": "Add Robot",
|
||||||
|
"Delete Garage": "Delete Garage",
|
||||||
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
"#4": "Phrases in basic/RobotPage/TokenInput.tsx",
|
||||||
"Download token and PGP credentials": "Download token and PGP credentials",
|
|
||||||
"Copied!": "已複製!",
|
"Copied!": "已複製!",
|
||||||
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
"#5": "Phrases in basic/RobotPage/Onboarding.tsx",
|
||||||
"1. Generate a token": "1. Generate a token",
|
"1. Generate a token": "1. Generate a token",
|
||||||
@ -144,7 +147,7 @@
|
|||||||
"Public sell orders": "公開出售訂單",
|
"Public sell orders": "公開出售訂單",
|
||||||
"Book liquidity": "賬面流動性",
|
"Book liquidity": "賬面流動性",
|
||||||
"Today active robots": "今天活躍的機器人",
|
"Today active robots": "今天活躍的機器人",
|
||||||
"24h non-KYC bitcoin premium": "24小時 non-KYC 比特幣溢價",
|
"Last 24h mean premium": "Last 24h mean premium",
|
||||||
"Maker fee": "掛單方費用",
|
"Maker fee": "掛單方費用",
|
||||||
"Taker fee": "吃單方費用",
|
"Taker fee": "吃單方費用",
|
||||||
"Current onchain payout fee": "當前鏈上支付費用",
|
"Current onchain payout fee": "當前鏈上支付費用",
|
||||||
|
Loading…
Reference in New Issue
Block a user