mirror of
https://github.com/RoboSats/robosats.git
synced 2024-12-13 19:06:26 +00:00
Small fixes, fix reconnecting websockets, fix rewards webln
This commit is contained in:
parent
3b77a473f8
commit
0d180ee7c9
@ -10,7 +10,7 @@ import BookTable from '../../components/BookTable';
|
||||
|
||||
// Icons
|
||||
import { BarChart, FormatListBulleted } from '@mui/icons-material';
|
||||
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
|
||||
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
|
||||
|
||||
const BookPage = (): JSX.Element => {
|
||||
const { robot, fetchBook, windowSize, setDelay, setOrder } =
|
||||
@ -47,13 +47,22 @@ const BookPage = (): JSX.Element => {
|
||||
const NavButtons = function () {
|
||||
return (
|
||||
<ButtonGroup variant='contained' color='inherit'>
|
||||
<Button color='primary' onClick={() => setOpenMaker(true)}>
|
||||
<Button
|
||||
color='primary'
|
||||
onClick={() => {
|
||||
setOpenMaker(true);
|
||||
}}
|
||||
>
|
||||
{t('Create')}
|
||||
</Button>
|
||||
{doubleView ? (
|
||||
<></>
|
||||
) : (
|
||||
<Button onClick={() => setView(view === 'depth' ? 'list' : 'depth')}>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setView(view === 'depth' ? 'list' : 'depth');
|
||||
}}
|
||||
>
|
||||
{view == 'depth' ? (
|
||||
<>
|
||||
<FormatListBulleted /> {t('List')}
|
||||
@ -71,9 +80,19 @@ const BookPage = (): JSX.Element => {
|
||||
|
||||
return (
|
||||
<Grid container direction='column' alignItems='center' spacing={1} sx={{ minWidth: 400 }}>
|
||||
<NoRobotDialog open={openNoRobot} onClose={() => setOpenNoRobot(false)} />
|
||||
<NoRobotDialog
|
||||
open={openNoRobot}
|
||||
onClose={() => {
|
||||
setOpenNoRobot(false);
|
||||
}}
|
||||
/>
|
||||
{openMaker ? (
|
||||
<Dialog open={openMaker} onClose={() => setOpenMaker(false)}>
|
||||
<Dialog
|
||||
open={openMaker}
|
||||
onClose={() => {
|
||||
setOpenMaker(false);
|
||||
}}
|
||||
>
|
||||
<Box sx={{ maxWidth: '18em', padding: '0.5em' }}>
|
||||
<MakerForm
|
||||
onOrderCreated={(id) => {
|
||||
|
@ -14,7 +14,7 @@ import RobotAvatar from '../components/RobotAvatar';
|
||||
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Notifications from '../components/Notifications';
|
||||
import { UseAppStoreType, AppContext, closeAll } from '../contexts/AppContext';
|
||||
import { type UseAppStoreType, AppContext, closeAll } from '../contexts/AppContext';
|
||||
|
||||
const Router = window.NativeRobosats === undefined ? BrowserRouter : MemoryRouter;
|
||||
|
||||
@ -54,16 +54,18 @@ const Main: React.FC = () => {
|
||||
style={{ display: 'none' }}
|
||||
nickname={robot.nickname}
|
||||
baseUrl={baseUrl}
|
||||
onLoad={() =>
|
||||
onLoad={() => {
|
||||
setRobot((robot) => {
|
||||
return { ...robot, avatarLoaded: true };
|
||||
})
|
||||
}
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Notifications
|
||||
order={order}
|
||||
page={page}
|
||||
openProfile={() => setOpen({ ...closeAll, profile: true })}
|
||||
openProfile={() => {
|
||||
setOpen({ ...closeAll, profile: true });
|
||||
}}
|
||||
rewards={robot.earnedRewards}
|
||||
windowWidth={windowSize.width}
|
||||
/>
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
UpdateClientDialog,
|
||||
} from '../../components/Dialogs';
|
||||
import { pn } from '../../utils';
|
||||
import { AppContext, UseAppStoreType, closeAll } from '../../contexts/AppContext';
|
||||
import { AppContext, type UseAppStoreType, closeAll } from '../../contexts/AppContext';
|
||||
|
||||
export interface OpenDialogs {
|
||||
more: boolean;
|
||||
@ -46,32 +46,49 @@ const MainDialogs = (): JSX.Element => {
|
||||
open={open.update}
|
||||
coordinatorVersion={info.coordinatorVersion}
|
||||
clientVersion={info.clientVersion}
|
||||
onClose={() => setOpen({ ...open, update: false })}
|
||||
onClose={() => {
|
||||
setOpen({ ...open, update: false });
|
||||
}}
|
||||
/>
|
||||
<InfoDialog
|
||||
open={open.info}
|
||||
maxAmount={maxAmount}
|
||||
onClose={() => setOpen({ ...open, info: false })}
|
||||
onClose={() => {
|
||||
setOpen({ ...open, info: false });
|
||||
}}
|
||||
/>
|
||||
<LearnDialog
|
||||
open={open.learn}
|
||||
onClose={() => {
|
||||
setOpen({ ...open, learn: false });
|
||||
}}
|
||||
/>
|
||||
<LearnDialog open={open.learn} onClose={() => setOpen({ ...open, learn: false })} />
|
||||
<CommunityDialog
|
||||
open={open.community}
|
||||
onClose={() => setOpen({ ...open, community: false })}
|
||||
onClose={() => {
|
||||
setOpen({ ...open, community: false });
|
||||
}}
|
||||
/>
|
||||
<CoordinatorSummaryDialog
|
||||
open={open.coordinator}
|
||||
onClose={() => setOpen({ ...open, coordinator: false })}
|
||||
onClose={() => {
|
||||
setOpen({ ...open, coordinator: false });
|
||||
}}
|
||||
info={info}
|
||||
/>
|
||||
<StatsDialog
|
||||
open={open.stats}
|
||||
onClose={() => setOpen({ ...open, stats: false })}
|
||||
onClose={() => {
|
||||
setOpen({ ...open, stats: false });
|
||||
}}
|
||||
info={info}
|
||||
/>
|
||||
<ProfileDialog
|
||||
open={open.profile}
|
||||
baseUrl={baseUrl}
|
||||
onClose={() => setOpen({ ...open, profile: false })}
|
||||
onClose={() => {
|
||||
setOpen({ ...open, profile: false });
|
||||
}}
|
||||
robot={robot}
|
||||
setRobot={setRobot}
|
||||
setCurrentOrder={setCurrentOrder}
|
||||
|
@ -8,7 +8,7 @@ import { filterOrders } from '../../utils';
|
||||
import MakerForm from '../../components/MakerForm';
|
||||
import BookTable from '../../components/BookTable';
|
||||
|
||||
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
|
||||
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
|
||||
import { NoRobotDialog } from '../../components/Dialogs';
|
||||
|
||||
const MakerPage = (): JSX.Element => {
|
||||
@ -64,7 +64,12 @@ const MakerPage = (): JSX.Element => {
|
||||
|
||||
return (
|
||||
<Grid container direction='column' alignItems='center' spacing={1}>
|
||||
<NoRobotDialog open={openNoRobot} onClose={() => setOpenNoRobot(false)} />
|
||||
<NoRobotDialog
|
||||
open={openNoRobot}
|
||||
onClose={() => {
|
||||
setOpenNoRobot(false);
|
||||
}}
|
||||
/>
|
||||
<Grid item>
|
||||
<Collapse in={matches.length > 0 && showMatches}>
|
||||
<Grid container direction='column' alignItems='center' spacing={1}>
|
||||
@ -102,8 +107,12 @@ const MakerPage = (): JSX.Element => {
|
||||
}}
|
||||
disableRequest={matches.length > 0 && !showMatches}
|
||||
collapseAll={showMatches}
|
||||
onSubmit={() => setShowMatches(matches.length > 0)}
|
||||
onReset={() => setShowMatches(false)}
|
||||
onSubmit={() => {
|
||||
setShowMatches(matches.length > 0);
|
||||
}}
|
||||
onReset={() => {
|
||||
setShowMatches(false);
|
||||
}}
|
||||
submitButtonLabel={matches.length > 0 && !showMatches ? 'Submit' : 'Create order'}
|
||||
/>
|
||||
</Paper>
|
||||
|
@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useTheme, styled, Grid, IconButton } from '@mui/material';
|
||||
import Tooltip, { TooltipProps, tooltipClasses } from '@mui/material/Tooltip';
|
||||
import Tooltip, { type TooltipProps, tooltipClasses } from '@mui/material/Tooltip';
|
||||
import { closeAll } from '../../contexts/AppContext';
|
||||
import { OpenDialogs } from '../MainDialogs';
|
||||
import { type OpenDialogs } from '../MainDialogs';
|
||||
|
||||
import { BubbleChart, Info, People, PriceChange, School } from '@mui/icons-material';
|
||||
|
||||
@ -45,7 +45,9 @@ const MoreTooltip = ({ open, setOpen, children }: MoreTooltipProps): JSX.Element
|
||||
sx={{
|
||||
color: open.info ? theme.palette.primary.main : theme.palette.text.secondary,
|
||||
}}
|
||||
onClick={() => setOpen({ ...closeAll, info: !open.info })}
|
||||
onClick={() => {
|
||||
setOpen({ ...closeAll, info: !open.info });
|
||||
}}
|
||||
>
|
||||
<Info />
|
||||
</IconButton>
|
||||
@ -58,7 +60,9 @@ const MoreTooltip = ({ open, setOpen, children }: MoreTooltipProps): JSX.Element
|
||||
sx={{
|
||||
color: open.learn ? theme.palette.primary.main : theme.palette.text.secondary,
|
||||
}}
|
||||
onClick={() => setOpen({ ...closeAll, learn: !open.learn })}
|
||||
onClick={() => {
|
||||
setOpen({ ...closeAll, learn: !open.learn });
|
||||
}}
|
||||
>
|
||||
<School />
|
||||
</IconButton>
|
||||
@ -75,7 +79,9 @@ const MoreTooltip = ({ open, setOpen, children }: MoreTooltipProps): JSX.Element
|
||||
sx={{
|
||||
color: open.community ? theme.palette.primary.main : theme.palette.text.secondary,
|
||||
}}
|
||||
onClick={() => setOpen({ ...closeAll, community: !open.community })}
|
||||
onClick={() => {
|
||||
setOpen({ ...closeAll, community: !open.community });
|
||||
}}
|
||||
>
|
||||
<People />
|
||||
</IconButton>
|
||||
@ -90,7 +96,9 @@ const MoreTooltip = ({ open, setOpen, children }: MoreTooltipProps): JSX.Element
|
||||
? theme.palette.primary.main
|
||||
: theme.palette.text.secondary,
|
||||
}}
|
||||
onClick={() => setOpen({ ...closeAll, coordinator: !open.coordinator })}
|
||||
onClick={() => {
|
||||
setOpen({ ...closeAll, coordinator: !open.coordinator });
|
||||
}}
|
||||
>
|
||||
<PriceChange />
|
||||
</IconButton>
|
||||
@ -103,7 +111,9 @@ const MoreTooltip = ({ open, setOpen, children }: MoreTooltipProps): JSX.Element
|
||||
sx={{
|
||||
color: open.stats ? theme.palette.primary.main : theme.palette.text.secondary,
|
||||
}}
|
||||
onClick={() => setOpen({ ...closeAll, stats: !open.stats })}
|
||||
onClick={() => {
|
||||
setOpen({ ...closeAll, stats: !open.stats });
|
||||
}}
|
||||
>
|
||||
<BubbleChart />
|
||||
</IconButton>
|
||||
|
@ -4,7 +4,7 @@ import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import { Tabs, Tab, Paper, useTheme } from '@mui/material';
|
||||
import MoreTooltip from './MoreTooltip';
|
||||
|
||||
import { Page } from '.';
|
||||
import { type Page } from '.';
|
||||
|
||||
import {
|
||||
SettingsApplications,
|
||||
@ -15,7 +15,7 @@ import {
|
||||
MoreHoriz,
|
||||
} from '@mui/icons-material';
|
||||
import RobotAvatar from '../../components/RobotAvatar';
|
||||
import { AppContext, UseAppStoreType, closeAll } from '../../contexts/AppContext';
|
||||
import { AppContext, type UseAppStoreType, closeAll } from '../../contexts/AppContext';
|
||||
|
||||
interface NavBarProps {
|
||||
width: number;
|
||||
@ -76,10 +76,9 @@ const NavBar = ({ width, height }: NavBarProps): JSX.Element => {
|
||||
handleSlideDirection(page, newPage);
|
||||
setPage(newPage);
|
||||
const param = newPage === 'order' ? currentOrder ?? '' : '';
|
||||
setTimeout(
|
||||
() => navigate(`/${newPage}/${param}`),
|
||||
theme.transitions.duration.leavingScreen * 3,
|
||||
);
|
||||
setTimeout(() => {
|
||||
navigate(`/${newPage}/${param}`);
|
||||
}, theme.transitions.duration.leavingScreen * 3);
|
||||
}
|
||||
};
|
||||
|
||||
@ -104,7 +103,9 @@ const NavBar = ({ width, height }: NavBarProps): JSX.Element => {
|
||||
sx={{ ...tabSx, minWidth: '2.5em', width: '2.5em', maxWidth: '4em' }}
|
||||
value='none'
|
||||
disabled={robot.nickname === null}
|
||||
onClick={() => setOpen({ ...closeAll, profile: !open.profile })}
|
||||
onClick={() => {
|
||||
setOpen({ ...closeAll, profile: !open.profile });
|
||||
}}
|
||||
icon={
|
||||
robot.nickname && robot.avatarLoaded ? (
|
||||
<RobotAvatar
|
||||
|
@ -7,7 +7,7 @@ import TradeBox from '../../components/TradeBox';
|
||||
import OrderDetails from '../../components/OrderDetails';
|
||||
|
||||
import { apiClient } from '../../services/api';
|
||||
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
|
||||
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
|
||||
|
||||
const OrderPage = (): JSX.Element => {
|
||||
const {
|
||||
@ -70,7 +70,9 @@ const OrderPage = (): JSX.Element => {
|
||||
}
|
||||
};
|
||||
|
||||
const startAgain = () => navigate('/robot');
|
||||
const startAgain = () => {
|
||||
navigate('/robot');
|
||||
};
|
||||
|
||||
return (
|
||||
<Box>
|
||||
@ -138,7 +140,9 @@ const OrderPage = (): JSX.Element => {
|
||||
<Box sx={{ borderBottom: 1, borderColor: 'divider', width: '21em' }}>
|
||||
<Tabs
|
||||
value={tab}
|
||||
onChange={(mouseEvent, value) => setTab(value)}
|
||||
onChange={(mouseEvent, value) => {
|
||||
setTab(value);
|
||||
}}
|
||||
variant='fullWidth'
|
||||
>
|
||||
<Tab label={t('Order')} value='order' />
|
||||
|
@ -15,7 +15,7 @@ import {
|
||||
AccordionSummary,
|
||||
AccordionDetails,
|
||||
} from '@mui/material';
|
||||
import { Robot } from '../../models';
|
||||
import { type Robot } from '../../models';
|
||||
import { Casino, Bolt, Check, Storefront, AddBox, School } from '@mui/icons-material';
|
||||
import RobotAvatar from '../../components/RobotAvatar';
|
||||
import TokenInput from './TokenInput';
|
||||
@ -54,7 +54,9 @@ const Onboarding = ({
|
||||
setGeneratedToken(true);
|
||||
setInputToken(genBase62Token(36));
|
||||
setLoading(true);
|
||||
setTimeout(() => setLoading(false), 1000);
|
||||
setTimeout(() => {
|
||||
setLoading(false);
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
return (
|
||||
@ -209,7 +211,13 @@ const Onboarding = ({
|
||||
) : null}
|
||||
<Grid item>
|
||||
<Collapse in={!!(robot.avatarLoaded && robot.nickname)}>
|
||||
<Button onClick={() => setStep('3')} variant='contained' size='large'>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setStep('3');
|
||||
}}
|
||||
variant='contained'
|
||||
size='large'
|
||||
>
|
||||
<Check />
|
||||
{t('Continue')}
|
||||
</Button>
|
||||
@ -237,11 +245,21 @@ const Onboarding = ({
|
||||
|
||||
<Grid item>
|
||||
<ButtonGroup variant='contained'>
|
||||
<Button color='primary' onClick={() => navigate('/offers')}>
|
||||
<Button
|
||||
color='primary'
|
||||
onClick={() => {
|
||||
navigate('/offers');
|
||||
}}
|
||||
>
|
||||
<Storefront /> <div style={{ width: '0.5em' }} />
|
||||
{t('Offers')}
|
||||
</Button>
|
||||
<Button color='secondary' onClick={() => navigate('/create')}>
|
||||
<Button
|
||||
color='secondary'
|
||||
onClick={() => {
|
||||
navigate('/create');
|
||||
}}
|
||||
>
|
||||
<AddBox /> <div style={{ width: '0.5em' }} />
|
||||
{t('Create')}
|
||||
</Button>
|
||||
@ -273,7 +291,12 @@ const Onboarding = ({
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid item sx={{ position: 'relative', top: '0.6em' }}>
|
||||
<Button color='inherit' onClick={() => setView('profile')}>
|
||||
<Button
|
||||
color='inherit'
|
||||
onClick={() => {
|
||||
setView('profile');
|
||||
}}
|
||||
>
|
||||
{t('See profile')}
|
||||
</Button>
|
||||
</Grid>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button, Grid, Typography } from '@mui/material';
|
||||
import { Robot } from '../../models';
|
||||
import { type Robot } from '../../models';
|
||||
import TokenInput from './TokenInput';
|
||||
import Key from '@mui/icons-material/Key';
|
||||
|
||||
|
@ -16,8 +16,8 @@ import {
|
||||
import { Bolt, Add, DeleteSweep, Logout, Download } from '@mui/icons-material';
|
||||
import RobotAvatar from '../../components/RobotAvatar';
|
||||
import TokenInput from './TokenInput';
|
||||
import { Slot, Robot } from '../../models';
|
||||
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
|
||||
import { type Slot, type Robot } from '../../models';
|
||||
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
|
||||
import { genBase62Token } from '../../utils';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
|
||||
@ -298,7 +298,12 @@ const RobotProfile = ({
|
||||
|
||||
{window.NativeRobosats === undefined ? (
|
||||
<Grid item>
|
||||
<Button color='primary' onClick={() => garage.download()}>
|
||||
<Button
|
||||
color='primary'
|
||||
onClick={() => {
|
||||
garage.download();
|
||||
}}
|
||||
>
|
||||
<Download />
|
||||
</Button>
|
||||
</Grid>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { IconButton, LinearProgress, TextField, Tooltip } from '@mui/material';
|
||||
import { Robot } from '../../models';
|
||||
import { type Robot } from '../../models';
|
||||
import { ContentCopy } from '@mui/icons-material';
|
||||
import { systemClient } from '../../services/System';
|
||||
|
||||
@ -57,7 +57,9 @@ const TokenInput = ({
|
||||
variant={editable ? 'outlined' : 'filled'}
|
||||
helperText={badToken}
|
||||
size='medium'
|
||||
onChange={(e) => setInputToken(e.target.value)}
|
||||
onChange={(e) => {
|
||||
setInputToken(e.target.value);
|
||||
}}
|
||||
onKeyPress={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
onPressEnter();
|
||||
@ -72,7 +74,9 @@ const TokenInput = ({
|
||||
onClick={() => {
|
||||
systemClient.copyToClipboard(inputToken);
|
||||
setShowCopied(true);
|
||||
setTimeout(() => setShowCopied(false), 1000);
|
||||
setTimeout(() => {
|
||||
setShowCopied(false);
|
||||
}, 1000);
|
||||
setRobot((robot) => {
|
||||
return { ...robot, copiedToken: true };
|
||||
});
|
||||
|
@ -73,7 +73,9 @@ const Welcome = ({ setView, width, getGenerateRobot }: WelcomeProps): JSX.Elemen
|
||||
size='large'
|
||||
color='primary'
|
||||
variant='contained'
|
||||
onClick={() => setView('onboarding')}
|
||||
onClick={() => {
|
||||
setView('onboarding');
|
||||
}}
|
||||
>
|
||||
<RocketLaunch />
|
||||
<div style={{ width: '0.5em' }} />
|
||||
@ -91,7 +93,9 @@ const Welcome = ({ setView, width, getGenerateRobot }: WelcomeProps): JSX.Elemen
|
||||
size='small'
|
||||
color='secondary'
|
||||
variant='contained'
|
||||
onClick={() => setView('recovery')}
|
||||
onClick={() => {
|
||||
setView('recovery');
|
||||
}}
|
||||
>
|
||||
<Key /> <div style={{ width: '0.5em' }} />
|
||||
{t('Recovery')}
|
||||
|
@ -19,7 +19,7 @@ import RobotProfile from './RobotProfile';
|
||||
import Recovery from './Recovery';
|
||||
import { TorIcon } from '../../components/Icons';
|
||||
import { genKey } from '../../pgp';
|
||||
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
|
||||
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
|
||||
import { validateTokenEntropy } from '../../utils';
|
||||
|
||||
const RobotPage = (): JSX.Element => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { Grid, Paper } from '@mui/material';
|
||||
import SettingsForm from '../../components/SettingsForm';
|
||||
import { UseAppStoreType, AppContext } from '../../contexts/AppContext';
|
||||
import { type UseAppStoreType, AppContext } from '../../contexts/AppContext';
|
||||
|
||||
const SettingsPage = (): JSX.Element => {
|
||||
const { windowSize, navbarHeight } = useContext<UseAppStoreType>(AppContext);
|
||||
|
@ -18,7 +18,7 @@ import { fiatMethods, swapMethods, PaymentIcon } from '../PaymentMethods';
|
||||
import { FlagWithProps } from '../Icons';
|
||||
|
||||
import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank';
|
||||
import { Favorites } from '../../models';
|
||||
import { type Favorites } from '../../models';
|
||||
import SwapCalls from '@mui/icons-material/SwapCalls';
|
||||
|
||||
interface BookControlProps {
|
||||
@ -259,7 +259,9 @@ const BookControl = ({
|
||||
style: { textAlign: 'center' },
|
||||
}}
|
||||
value={paymentMethod[0] ? paymentMethod[0] : 'ANY'}
|
||||
onChange={(e) => setPaymentMethods(e.target.value == 'ANY' ? [] : [e.target.value])}
|
||||
onChange={(e) => {
|
||||
setPaymentMethods(e.target.value == 'ANY' ? [] : [e.target.value]);
|
||||
}}
|
||||
>
|
||||
<MenuItem value={'ANY'}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap' }}>
|
||||
|
@ -14,17 +14,17 @@ import {
|
||||
LinearProgress,
|
||||
IconButton,
|
||||
Tooltip,
|
||||
LinearProgressProps,
|
||||
type LinearProgressProps,
|
||||
styled,
|
||||
} from '@mui/material';
|
||||
import {
|
||||
DataGrid,
|
||||
GridColumnVisibilityModel,
|
||||
type GridColumnVisibilityModel,
|
||||
GridPagination,
|
||||
GridPaginationModel,
|
||||
type GridPaginationModel,
|
||||
} from '@mui/x-data-grid';
|
||||
import currencyDict from '../../../static/assets/currencies.json';
|
||||
import { PublicOrder } from '../../models';
|
||||
import { type PublicOrder } from '../../models';
|
||||
import { filterOrders, hexToRgb, statusBadgeColor, pn, amountToString } from '../../utils';
|
||||
import BookControl from './BookControl';
|
||||
|
||||
@ -34,7 +34,7 @@ import RobotAvatar from '../RobotAvatar';
|
||||
|
||||
// Icons
|
||||
import { Fullscreen, FullscreenExit, Refresh } from '@mui/icons-material';
|
||||
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
|
||||
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
|
||||
|
||||
const ClickThroughDataGrid = styled(DataGrid)({
|
||||
'& .MuiDataGrid-overlayWrapperInner': {
|
||||
@ -609,7 +609,7 @@ const BookTable = ({
|
||||
const filteredColumns = function (maxWidth: number) {
|
||||
const useSmall = maxWidth < 70;
|
||||
const selectedColumns: object[] = [];
|
||||
let columnVisibilityModel: GridColumnVisibilityModel = {};
|
||||
const columnVisibilityModel: GridColumnVisibilityModel = {};
|
||||
let width: number = 0;
|
||||
|
||||
for (const [key, value] of Object.entries(columnSpecs)) {
|
||||
@ -654,12 +654,20 @@ const BookTable = ({
|
||||
<Grid item>
|
||||
<Grid container alignItems='center' direction='row'>
|
||||
<Grid item xs={6}>
|
||||
<IconButton onClick={() => setFullscreen(!fullscreen)}>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
setFullscreen(!fullscreen);
|
||||
}}
|
||||
>
|
||||
{fullscreen ? <FullscreenExit /> : <Fullscreen />}
|
||||
</IconButton>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<IconButton onClick={() => fetchBook()}>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
fetchBook();
|
||||
}}
|
||||
>
|
||||
<Refresh />
|
||||
</IconButton>
|
||||
</Grid>
|
||||
@ -758,9 +766,9 @@ const BookTable = ({
|
||||
loading={book.loading}
|
||||
columns={columns}
|
||||
columnVisibilityModel={columnVisibilityModel}
|
||||
onColumnVisibilityModelChange={(newColumnVisibilityModel) =>
|
||||
setColumnVisibilityModel(newColumnVisibilityModel)
|
||||
}
|
||||
onColumnVisibilityModelChange={(newColumnVisibilityModel) => {
|
||||
setColumnVisibilityModel(newColumnVisibilityModel);
|
||||
}}
|
||||
hideFooter={!showFooter}
|
||||
components={gridComponents}
|
||||
componentsProps={{
|
||||
@ -777,7 +785,9 @@ const BookTable = ({
|
||||
onPaginationModelChange={(newPaginationModel) => {
|
||||
setPaginationModel(newPaginationModel);
|
||||
}}
|
||||
onRowClick={(params: any) => onOrderClicked(params.row.id)}
|
||||
onRowClick={(params: any) => {
|
||||
onOrderClicked(params.row.id);
|
||||
}}
|
||||
/>
|
||||
</Paper>
|
||||
);
|
||||
@ -795,9 +805,9 @@ const BookTable = ({
|
||||
hideFooter={!showFooter}
|
||||
components={gridComponents}
|
||||
columnVisibilityModel={columnVisibilityModel}
|
||||
onColumnVisibilityModelChange={(newColumnVisibilityModel) =>
|
||||
setColumnVisibilityModel(newColumnVisibilityModel)
|
||||
}
|
||||
onColumnVisibilityModelChange={(newColumnVisibilityModel) => {
|
||||
setColumnVisibilityModel(newColumnVisibilityModel);
|
||||
}}
|
||||
componentsProps={{
|
||||
toolbar: {
|
||||
width,
|
||||
@ -812,7 +822,9 @@ const BookTable = ({
|
||||
onPaginationModelChange={(newPaginationModel) => {
|
||||
setPaginationModel(newPaginationModel);
|
||||
}}
|
||||
onRowClick={(params: any) => onOrderClicked(params.row.id)}
|
||||
onRowClick={(params: any) => {
|
||||
onOrderClicked(params.row.id);
|
||||
}}
|
||||
/>
|
||||
</Paper>
|
||||
</Dialog>
|
||||
|
@ -1,12 +1,12 @@
|
||||
import React, { useEffect, useState, useContext } from 'react';
|
||||
import {
|
||||
ResponsiveLine,
|
||||
Serie,
|
||||
Datum,
|
||||
PointTooltipProps,
|
||||
PointMouseHandler,
|
||||
Point,
|
||||
CustomLayer,
|
||||
type Serie,
|
||||
type Datum,
|
||||
type PointTooltipProps,
|
||||
type PointMouseHandler,
|
||||
type Point,
|
||||
type CustomLayer,
|
||||
} from '@nivo/line';
|
||||
import {
|
||||
Box,
|
||||
@ -20,13 +20,13 @@ import {
|
||||
} from '@mui/material';
|
||||
import { AddCircleOutline, RemoveCircleOutline } from '@mui/icons-material';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PublicOrder, LimitList, Order } from '../../../models';
|
||||
import { type PublicOrder, LimitList, type Order } from '../../../models';
|
||||
import RobotAvatar from '../../RobotAvatar';
|
||||
import { amountToString, matchMedian, statusBadgeColor } from '../../../utils';
|
||||
import currencyDict from '../../../../static/assets/currencies.json';
|
||||
import { PaymentStringAsIcons } from '../../PaymentMethods';
|
||||
import getNivoScheme from '../NivoScheme';
|
||||
import { UseAppStoreType, AppContext } from '../../../contexts/AppContext';
|
||||
import { type UseAppStoreType, AppContext } from '../../../contexts/AppContext';
|
||||
|
||||
interface DepthChartProps {
|
||||
maxWidth: number;
|
||||
@ -316,7 +316,13 @@ const DepthChart: React.FC<DepthChartProps> = ({
|
||||
alignItems='flex-start'
|
||||
style={{ paddingLeft: '1em' }}
|
||||
>
|
||||
<Select variant='standard' value={xType} onChange={(e) => setXType(e.target.value)}>
|
||||
<Select
|
||||
variant='standard'
|
||||
value={xType}
|
||||
onChange={(e) => {
|
||||
setXType(e.target.value);
|
||||
}}
|
||||
>
|
||||
<MenuItem value={'premium'}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap' }}>
|
||||
{t('Premium')}
|
||||
@ -333,7 +339,11 @@ const DepthChart: React.FC<DepthChartProps> = ({
|
||||
<Grid container direction='row' justifyContent='center' alignItems='center'>
|
||||
<Grid container justifyContent='center' alignItems='center'>
|
||||
<Grid item>
|
||||
<IconButton onClick={() => setXRange(xRange + rangeSteps)}>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
setXRange(xRange + rangeSteps);
|
||||
}}
|
||||
>
|
||||
<RemoveCircleOutline />
|
||||
</IconButton>
|
||||
</Grid>
|
||||
@ -345,7 +355,12 @@ const DepthChart: React.FC<DepthChartProps> = ({
|
||||
</Box>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<IconButton onClick={() => setXRange(xRange - rangeSteps)} disabled={xRange <= 1}>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
setXRange(xRange - rangeSteps);
|
||||
}}
|
||||
disabled={xRange <= 1}
|
||||
>
|
||||
<AddCircleOutline />
|
||||
</IconButton>
|
||||
</Grid>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Theme as NivoTheme } from '@nivo/core';
|
||||
import { Theme as MuiTheme } from '@mui/material/styles';
|
||||
import { type Theme as NivoTheme } from '@nivo/core';
|
||||
import { type Theme as MuiTheme } from '@mui/material/styles';
|
||||
|
||||
export const getNivoScheme: (theme: MuiTheme) => NivoTheme = (theme) => {
|
||||
const lightMode = {
|
||||
|
@ -37,7 +37,11 @@ function CredentialTextfield(props) {
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<Tooltip disableHoverListener enterTouchDelay={0} title={props.copiedTitle}>
|
||||
<IconButton onClick={() => systemClient.copyToClipboard(props.value)}>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
systemClient.copyToClipboard(props.value);
|
||||
}}
|
||||
>
|
||||
<ContentCopy />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
@ -144,14 +148,14 @@ const AuditPGPDialog = ({
|
||||
size='small'
|
||||
color='primary'
|
||||
variant='contained'
|
||||
onClick={() =>
|
||||
onClick={() => {
|
||||
saveAsJson('keys_' + orderId + '.json', {
|
||||
own_public_key: own_pub_key,
|
||||
peer_public_key: peer_pub_key,
|
||||
encrypted_private_key: own_enc_priv_key,
|
||||
passphrase,
|
||||
})
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
<div style={{ width: 26, height: 18 }}>
|
||||
<ExportIcon sx={{ width: 18, height: 18 }} />
|
||||
@ -176,7 +180,9 @@ const AuditPGPDialog = ({
|
||||
size='small'
|
||||
color='primary'
|
||||
variant='contained'
|
||||
onClick={() => saveAsJson('messages_' + orderId + '.json', messages)}
|
||||
onClick={() => {
|
||||
saveAsJson('messages_' + orderId + '.json', messages);
|
||||
}}
|
||||
>
|
||||
<div style={{ width: 28, height: 20 }}>
|
||||
<ExportIcon sx={{ width: 18, height: 18 }} />
|
||||
|
@ -23,7 +23,7 @@ import BookIcon from '@mui/icons-material/Book';
|
||||
import LinkIcon from '@mui/icons-material/Link';
|
||||
|
||||
import { pn } from '../../utils';
|
||||
import { Info } from '../../models';
|
||||
import { type Info } from '../../models';
|
||||
|
||||
interface Props {
|
||||
open: boolean;
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
Grid,
|
||||
} from '@mui/material';
|
||||
import { NewTabIcon } from '../Icons';
|
||||
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
|
||||
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
|
||||
|
||||
interface Props {
|
||||
open: boolean;
|
||||
|
@ -33,10 +33,10 @@ import NumbersIcon from '@mui/icons-material/Numbers';
|
||||
import EmojiEventsIcon from '@mui/icons-material/EmojiEvents';
|
||||
import { UserNinjaIcon } from '../Icons';
|
||||
|
||||
import { getHost, getWebln } from '../../utils';
|
||||
import { getWebln } from '../../utils';
|
||||
import RobotAvatar from '../RobotAvatar';
|
||||
import { apiClient } from '../../services/api';
|
||||
import { Robot } from '../../models';
|
||||
import { type Robot } from '../../models';
|
||||
|
||||
interface Props {
|
||||
open: boolean;
|
||||
@ -50,7 +50,6 @@ const ProfileDialog = ({ open = false, baseUrl, onClose, robot, setRobot }: Prop
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const theme = useTheme();
|
||||
const host = getHost();
|
||||
|
||||
const [rewardInvoice, setRewardInvoice] = useState<string>('');
|
||||
const [showRewardsSpinner, setShowRewardsSpinner] = useState<boolean>(false);
|
||||
@ -60,13 +59,20 @@ const ProfileDialog = ({ open = false, baseUrl, onClose, robot, setRobot }: Prop
|
||||
const [weblnEnabled, setWeblnEnabled] = useState<boolean>(false);
|
||||
const [openEnableTelegram, setOpenEnableTelegram] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
const handleWebln = async (order: Order) => {
|
||||
const webln = await getWebln().catch(() => console.log('WebLN not available'));
|
||||
const handleWebln = async () => {
|
||||
const webln = await getWebln()
|
||||
.then(() => {
|
||||
setWeblnEnabled(true);
|
||||
})
|
||||
.catch(() => {
|
||||
setWeblnEnabled(false);
|
||||
console.log('WebLN not available');
|
||||
});
|
||||
return webln;
|
||||
};
|
||||
const webln = handleWebln();
|
||||
setWeblnEnabled(webln !== undefined);
|
||||
|
||||
useEffect(() => {
|
||||
handleWebln();
|
||||
}, []);
|
||||
|
||||
const handleWeblnInvoiceClicked = async (e: any) => {
|
||||
@ -107,7 +113,9 @@ const ProfileDialog = ({ open = false, baseUrl, onClose, robot, setRobot }: Prop
|
||||
const setStealthInvoice = (wantsStealth: boolean) => {
|
||||
apiClient
|
||||
.post(baseUrl, '/api/stealth/', { wantsStealth }, { tokenSHA256: robot.tokenSHA256 })
|
||||
.then((data) => setRobot({ ...robot, stealthInvoices: data?.wantsStealth }));
|
||||
.then((data) => {
|
||||
setRobot({ ...robot, stealthInvoices: data?.wantsStealth });
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
@ -213,7 +221,9 @@ const ProfileDialog = ({ open = false, baseUrl, onClose, robot, setRobot }: Prop
|
||||
|
||||
<EnableTelegramDialog
|
||||
open={openEnableTelegram}
|
||||
onClose={() => setOpenEnableTelegram(false)}
|
||||
onClose={() => {
|
||||
setOpenEnableTelegram(false);
|
||||
}}
|
||||
tgBotName={robot.tgBotName}
|
||||
tgToken={robot.tgToken}
|
||||
/>
|
||||
@ -229,7 +239,12 @@ const ProfileDialog = ({ open = false, baseUrl, onClose, robot, setRobot }: Prop
|
||||
<b>{t('Telegram enabled')}</b>
|
||||
</Typography>
|
||||
) : (
|
||||
<Button color='primary' onClick={() => setOpenEnableTelegram(true)}>
|
||||
<Button
|
||||
color='primary'
|
||||
onClick={() => {
|
||||
setOpenEnableTelegram(true);
|
||||
}}
|
||||
>
|
||||
{t('Enable Telegram Notifications')}
|
||||
</Button>
|
||||
)}
|
||||
@ -256,7 +271,9 @@ const ProfileDialog = ({ open = false, baseUrl, onClose, robot, setRobot }: Prop
|
||||
control={
|
||||
<Switch
|
||||
checked={robot.stealthInvoices}
|
||||
onChange={() => setStealthInvoice(!robot.stealthInvoices)}
|
||||
onChange={() => {
|
||||
setStealthInvoice(!robot.stealthInvoices);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
@ -280,7 +297,9 @@ const ProfileDialog = ({ open = false, baseUrl, onClose, robot, setRobot }: Prop
|
||||
<Grid item xs={3}>
|
||||
<Button
|
||||
disabled={robot.earnedRewards === 0}
|
||||
onClick={() => setOpenClaimRewards(true)}
|
||||
onClick={() => {
|
||||
setOpenClaimRewards(true);
|
||||
}}
|
||||
variant='contained'
|
||||
size='small'
|
||||
>
|
||||
@ -309,7 +328,9 @@ const ProfileDialog = ({ open = false, baseUrl, onClose, robot, setRobot }: Prop
|
||||
<Grid item alignItems='stretch' style={{ display: 'flex', maxWidth: 80 }}>
|
||||
<Button
|
||||
sx={{ maxHeight: 38 }}
|
||||
onClick={(e) => handleSubmitInvoiceClicked(e, rewardInvoice)}
|
||||
onClick={(e) => {
|
||||
handleSubmitInvoiceClicked(e, rewardInvoice);
|
||||
}}
|
||||
variant='contained'
|
||||
color='primary'
|
||||
size='small'
|
||||
@ -319,12 +340,14 @@ const ProfileDialog = ({ open = false, baseUrl, onClose, robot, setRobot }: Prop
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
{weblnEnabled && (
|
||||
{weblnEnabled ? (
|
||||
<Grid container style={{ display: 'flex', alignItems: 'stretch' }}>
|
||||
<Grid item alignItems='stretch' style={{ display: 'flex', maxWidth: 240 }}>
|
||||
<Button
|
||||
sx={{ maxHeight: 38, minWidth: 230 }}
|
||||
onClick={async (e) => await handleWeblnInvoiceClicked(e)}
|
||||
onClick={async (e) => {
|
||||
await handleWeblnInvoiceClicked(e);
|
||||
}}
|
||||
variant='contained'
|
||||
color='primary'
|
||||
size='small'
|
||||
@ -334,6 +357,8 @@ const ProfileDialog = ({ open = false, baseUrl, onClose, robot, setRobot }: Prop
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</form>
|
||||
)}
|
||||
|
@ -25,7 +25,7 @@ import EqualizerIcon from '@mui/icons-material/Equalizer';
|
||||
import { AmbossIcon, BitcoinSignIcon, RoboSatsNoTextIcon } from '../Icons';
|
||||
|
||||
import { pn } from '../../utils';
|
||||
import { Info } from '../../models';
|
||||
import { type Info } from '../../models';
|
||||
|
||||
interface Props {
|
||||
open: boolean;
|
||||
|
@ -14,7 +14,7 @@ import {
|
||||
} from '@mui/material';
|
||||
import { systemClient } from '../../services/System';
|
||||
import ContentCopy from '@mui/icons-material/ContentCopy';
|
||||
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
|
||||
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
|
||||
|
||||
interface Props {
|
||||
open: boolean;
|
||||
@ -49,7 +49,11 @@ const StoreTokenDialog = ({ open, onClose, onClickBack, onClickDone }: Props): J
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<Tooltip disableHoverListener enterTouchDelay={0} title={t('Copied!')}>
|
||||
<IconButton onClick={() => systemClient.copyToClipboard(robot.token)}>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
systemClient.copyToClipboard(robot.token);
|
||||
}}
|
||||
>
|
||||
<ContentCopy color='primary' />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
|
@ -88,7 +88,12 @@ const UpdateClientDialog = ({
|
||||
|
||||
<Divider />
|
||||
|
||||
<ListItemButton component='a' onClick={() => location.reload(true)}>
|
||||
<ListItemButton
|
||||
component='a'
|
||||
onClick={() => {
|
||||
location.reload(true);
|
||||
}}
|
||||
>
|
||||
<ListItemIcon>
|
||||
<WebIcon color='primary' sx={{ height: 32, width: 32 }} />
|
||||
</ListItemIcon>
|
||||
|
@ -29,6 +29,7 @@ export default class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBo
|
||||
window.location.reload();
|
||||
}, 30000);
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
return (
|
||||
|
@ -132,7 +132,9 @@ function AmountRange({
|
||||
}}
|
||||
value={currency == 0 ? 1 : currency}
|
||||
renderValue={() => currencyCode}
|
||||
onChange={(e) => handleCurrencyChange(e.target.value)}
|
||||
onChange={(e) => {
|
||||
handleCurrencyChange(e.target.value);
|
||||
}}
|
||||
>
|
||||
{Object.entries(currencyDict).map(([key, value]) => (
|
||||
<MenuItem key={key} value={parseInt(key)}>
|
||||
|
@ -226,9 +226,13 @@ export default function AutocompletePayments(props) {
|
||||
value: props.value,
|
||||
options: props.optionsType == 'fiat' ? fiatMethods : swapMethods,
|
||||
getOptionLabel: (option) => option.name,
|
||||
onInputChange: (e) => setVal(e ? (e.target.value ? e.target.value : '') : ''),
|
||||
onInputChange: (e) => {
|
||||
setVal(e ? (e.target.value ? e.target.value : '') : '');
|
||||
},
|
||||
onChange: (event, value) => props.onAutocompleteChange(value),
|
||||
onClose: () => setVal(() => ''),
|
||||
onClose: () => {
|
||||
setVal(() => '');
|
||||
},
|
||||
});
|
||||
|
||||
const [val, setVal] = useState('');
|
||||
|
@ -25,7 +25,7 @@ import {
|
||||
IconButton,
|
||||
} from '@mui/material';
|
||||
|
||||
import { LimitList, defaultMaker } from '../../models';
|
||||
import { type LimitList, defaultMaker } from '../../models';
|
||||
|
||||
import { LocalizationProvider, MobileTimePicker } from '@mui/x-date-pickers';
|
||||
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
|
||||
@ -40,7 +40,7 @@ import { amountToString, computeSats, pn } from '../../utils';
|
||||
|
||||
import { SelfImprovement, Lock, HourglassTop, DeleteSweep, Edit } from '@mui/icons-material';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
|
||||
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
|
||||
|
||||
interface MakerFormProps {
|
||||
disableRequest?: boolean;
|
||||
@ -464,7 +464,9 @@ const MakerForm = ({
|
||||
<Box>
|
||||
<ConfirmationDialog
|
||||
open={openDialogs}
|
||||
onClose={() => setOpenDialogs(false)}
|
||||
onClose={() => {
|
||||
setOpenDialogs(false);
|
||||
}}
|
||||
onClickDone={handleCreateOrder}
|
||||
hasRobot={robot.avatarLoaded}
|
||||
/>
|
||||
@ -531,7 +533,9 @@ const MakerForm = ({
|
||||
<Checkbox
|
||||
sx={{ position: 'relative', bottom: '0.3em' }}
|
||||
checked={fav.mode == 'swap'}
|
||||
onClick={() => handleCurrencyChange(fav.mode == 'swap' ? 1 : 1000)}
|
||||
onClick={() => {
|
||||
handleCurrencyChange(fav.mode == 'swap' ? 1 : 1000);
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
</Grid>
|
||||
@ -547,12 +551,12 @@ const MakerForm = ({
|
||||
<Button
|
||||
size={maker.advancedOptions ? 'small' : 'large'}
|
||||
variant='contained'
|
||||
onClick={() =>
|
||||
onClick={() => {
|
||||
setFav({
|
||||
...fav,
|
||||
type: 1,
|
||||
})
|
||||
}
|
||||
});
|
||||
}}
|
||||
disableElevation={fav.type == 1}
|
||||
sx={{
|
||||
backgroundColor: fav.type == 1 ? 'primary.main' : 'background.paper',
|
||||
@ -567,12 +571,12 @@ const MakerForm = ({
|
||||
<Button
|
||||
size={maker.advancedOptions ? 'small' : 'large'}
|
||||
variant='contained'
|
||||
onClick={() =>
|
||||
onClick={() => {
|
||||
setFav({
|
||||
...fav,
|
||||
type: 0,
|
||||
})
|
||||
}
|
||||
});
|
||||
}}
|
||||
disableElevation={fav.type == 0}
|
||||
color='secondary'
|
||||
sx={{
|
||||
@ -654,7 +658,9 @@ const MakerForm = ({
|
||||
borderRadius: '4px',
|
||||
},
|
||||
}}
|
||||
onChange={(e) => setMaker({ ...maker, amount: e.target.value })}
|
||||
onChange={(e) => {
|
||||
setMaker({ ...maker, amount: e.target.value });
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
{fav.mode === 'swap' && maker.amount != '' ? (
|
||||
@ -677,7 +683,9 @@ const MakerForm = ({
|
||||
style: { textAlign: 'center' },
|
||||
}}
|
||||
value={fav.currency == 0 ? 1 : fav.currency}
|
||||
onChange={(e) => handleCurrencyChange(e.target.value)}
|
||||
onChange={(e) => {
|
||||
handleCurrencyChange(e.target.value);
|
||||
}}
|
||||
>
|
||||
{Object.entries(currencyDict).map(([key, value]) => (
|
||||
<MenuItem key={key} value={parseInt(key)}>
|
||||
@ -946,7 +954,9 @@ const MakerForm = ({
|
||||
]}
|
||||
min={2}
|
||||
max={15}
|
||||
onChange={(e) => setMaker({ ...maker, bondSize: e.target.value })}
|
||||
onChange={(e) => {
|
||||
setMaker({ ...maker, bondSize: e.target.value });
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
@ -5,14 +5,14 @@ import {
|
||||
Alert,
|
||||
useTheme,
|
||||
IconButton,
|
||||
TooltipProps,
|
||||
type TooltipProps,
|
||||
styled,
|
||||
tooltipClasses,
|
||||
} from '@mui/material';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Order } from '../../models';
|
||||
import { type Order } from '../../models';
|
||||
import Close from '@mui/icons-material/Close';
|
||||
import { Page } from '../../basic/NavBar';
|
||||
import { type Page } from '../../basic/NavBar';
|
||||
|
||||
interface NotificationsProps {
|
||||
order: Order | undefined;
|
||||
@ -28,7 +28,7 @@ interface NotificationMessage {
|
||||
onClick: () => void;
|
||||
sound: HTMLAudioElement | undefined;
|
||||
timeout: number;
|
||||
pageTitle: String;
|
||||
pageTitle: string;
|
||||
}
|
||||
|
||||
const audio = {
|
||||
@ -207,7 +207,9 @@ const Notifications = ({
|
||||
if (message.title != '') {
|
||||
setMessage(message);
|
||||
setShow(true);
|
||||
setTimeout(() => setShow(false), message.timeout);
|
||||
setTimeout(() => {
|
||||
setShow(false);
|
||||
}, message.timeout);
|
||||
if (message.sound != null) {
|
||||
message.sound.play();
|
||||
}
|
||||
|
@ -21,11 +21,11 @@ import Countdown from 'react-countdown';
|
||||
import currencies from '../../../static/assets/currencies.json';
|
||||
import { apiClient } from '../../services/api';
|
||||
|
||||
import { Order, Info } from '../../models';
|
||||
import { type Order, type Info } from '../../models';
|
||||
import { ConfirmationDialog } from '../Dialogs';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
import { computeSats } from '../../utils';
|
||||
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
|
||||
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
|
||||
|
||||
interface TakeButtonProps {
|
||||
order: Order;
|
||||
@ -58,10 +58,10 @@ const TakeButton = ({ order, setOrder, baseUrl, info }: TakeButtonProps): JSX.El
|
||||
const rate = order.amount ? order.amount / btc_now : order.max_amount / btc_now;
|
||||
const amount = order.currency === 1000 ? Number(takeAmount) / 100000000 : Number(takeAmount);
|
||||
const satoshis = computeSats({
|
||||
amount: amount,
|
||||
amount,
|
||||
routingBudget: order.is_buyer ? defaultRoutingBudget : 0,
|
||||
fee: tradeFee,
|
||||
rate: rate,
|
||||
rate,
|
||||
});
|
||||
return satoshis;
|
||||
};
|
||||
@ -74,7 +74,12 @@ const TakeButton = ({ order, setOrder, baseUrl, info }: TakeButtonProps): JSX.El
|
||||
|
||||
const InactiveMakerDialog = function () {
|
||||
return (
|
||||
<Dialog open={open.inactiveMaker} onClose={() => setOpen({ ...open, inactiveMaker: false })}>
|
||||
<Dialog
|
||||
open={open.inactiveMaker}
|
||||
onClose={() => {
|
||||
setOpen({ ...open, inactiveMaker: false });
|
||||
}}
|
||||
>
|
||||
<DialogTitle>{t('The maker is away')}</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText>
|
||||
@ -84,10 +89,19 @@ const TakeButton = ({ order, setOrder, baseUrl, info }: TakeButtonProps): JSX.El
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={() => setOpen(closeAll)} autoFocus>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setOpen(closeAll);
|
||||
}}
|
||||
autoFocus
|
||||
>
|
||||
{t('Go back')}
|
||||
</Button>
|
||||
<Button onClick={() => setOpen({ inactiveMaker: false, confirmation: true })}>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setOpen({ inactiveMaker: false, confirmation: true });
|
||||
}}
|
||||
>
|
||||
{t('Sounds fine')}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
@ -313,7 +327,9 @@ const TakeButton = ({ order, setOrder, baseUrl, info }: TakeButtonProps): JSX.El
|
||||
|
||||
<ConfirmationDialog
|
||||
open={open.confirmation}
|
||||
onClose={() => setOpen({ ...open, confirmation: false })}
|
||||
onClose={() => {
|
||||
setOpen({ ...open, confirmation: false });
|
||||
}}
|
||||
onClickDone={() => {
|
||||
takeOrder();
|
||||
setLoadingTake(true);
|
||||
|
@ -16,7 +16,7 @@ import {
|
||||
IconButton,
|
||||
} from '@mui/material';
|
||||
|
||||
import Countdown, { CountdownRenderProps, zeroPad } from 'react-countdown';
|
||||
import Countdown, { type CountdownRenderProps, zeroPad } from 'react-countdown';
|
||||
import RobotAvatar from '../../components/RobotAvatar';
|
||||
|
||||
import currencies from '../../../static/assets/currencies.json';
|
||||
@ -34,7 +34,7 @@ import { PaymentStringAsIcons } from '../../components/PaymentMethods';
|
||||
import { FlagWithProps, SendReceiveIcon } from '../Icons';
|
||||
import LinearDeterminate from './LinearDeterminate';
|
||||
|
||||
import { Order, Info } from '../../models';
|
||||
import { type Order, type Info } from '../../models';
|
||||
import { statusBadgeColor, pn, amountToString, computeSats } from '../../utils';
|
||||
import TakeButton from './TakeButton';
|
||||
|
||||
@ -160,20 +160,20 @@ const OrderDetails = ({
|
||||
amount: order.amount,
|
||||
fee: -tradeFee,
|
||||
routingBudget: defaultRoutingBudget,
|
||||
rate: rate,
|
||||
rate,
|
||||
});
|
||||
} else {
|
||||
const min = computeSats({
|
||||
amount: Number(order.min_amount),
|
||||
fee: -tradeFee,
|
||||
routingBudget: defaultRoutingBudget,
|
||||
rate: rate,
|
||||
rate,
|
||||
});
|
||||
const max = computeSats({
|
||||
amount: Number(order.max_amount),
|
||||
fee: -tradeFee,
|
||||
routingBudget: defaultRoutingBudget,
|
||||
rate: rate,
|
||||
rate,
|
||||
});
|
||||
sats = `${min}-${max}`;
|
||||
}
|
||||
@ -190,18 +190,18 @@ const OrderDetails = ({
|
||||
sats = computeSats({
|
||||
amount: order.amount,
|
||||
fee: tradeFee,
|
||||
rate: rate,
|
||||
rate,
|
||||
});
|
||||
} else {
|
||||
const min = computeSats({
|
||||
amount: order.min_amount,
|
||||
fee: tradeFee,
|
||||
rate: rate,
|
||||
rate,
|
||||
});
|
||||
const max = computeSats({
|
||||
amount: order.max_amount,
|
||||
fee: tradeFee,
|
||||
rate: rate,
|
||||
rate,
|
||||
});
|
||||
sats = `${min}-${max}`;
|
||||
}
|
||||
@ -297,7 +297,11 @@ const OrderDetails = ({
|
||||
secondary={order.amount ? 'Amount' : 'Amount Range'}
|
||||
/>
|
||||
<ListItemIcon>
|
||||
<IconButton onClick={() => setShowSatsDetails(!showSatsDetails)}>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
setShowSatsDetails(!showSatsDetails);
|
||||
}}
|
||||
>
|
||||
{showSatsDetails ? <ExpandLess /> : <ExpandMore color='primary' />}
|
||||
</IconButton>
|
||||
</ListItemIcon>
|
||||
|
@ -105,7 +105,9 @@ const RobotAvatar: React.FC<Props> = ({
|
||||
border: '0.3px solid #55555',
|
||||
filter: 'dropShadow(0.5px 0.5px 0.5px #000000)',
|
||||
...imageStyle,
|
||||
onLoad: setTimeout(() => setActiveBackground(false), 1000),
|
||||
onLoad: setTimeout(() => {
|
||||
setActiveBackground(false);
|
||||
}, 1000),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Select, MenuItem, useTheme, Grid, Typography } from '@mui/material';
|
||||
import Language from '../../models/Language.model';
|
||||
import type Language from '../../models/Language.model';
|
||||
|
||||
import Flags from 'country-flag-icons/react/3x2';
|
||||
import { CataloniaFlag, BasqueCountryFlag } from '../Icons';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { UseAppStoreType, AppContext } from '../../contexts/AppContext';
|
||||
import { type UseAppStoreType, AppContext } from '../../contexts/AppContext';
|
||||
import {
|
||||
Grid,
|
||||
Paper,
|
||||
|
@ -2,7 +2,7 @@ import React, { useContext } from 'react';
|
||||
import { Box, CircularProgress, Tooltip } from '@mui/material';
|
||||
import { TorIcon } from './Icons';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { AppContext, UseAppStoreType } from '../contexts/AppContext';
|
||||
import { AppContext, type UseAppStoreType } from '../contexts/AppContext';
|
||||
|
||||
interface TorIndicatorProps {
|
||||
color: 'inherit' | 'error' | 'warning' | 'success' | 'primary' | 'secondary' | 'info' | undefined;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Box, Tooltip } from '@mui/material';
|
||||
import { Order } from '../../models';
|
||||
import { type Order } from '../../models';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
|
||||
interface CancelButtonProps {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Alert } from '@mui/material';
|
||||
import { Order } from '../../models';
|
||||
import { type Order } from '../../models';
|
||||
|
||||
interface CollabCancelAlertProps {
|
||||
order: Order;
|
||||
|
@ -12,7 +12,7 @@ import { LoadingButton } from '@mui/lab';
|
||||
|
||||
interface ConfirmCollabCancelDialogProps {
|
||||
open: boolean;
|
||||
loading: Boolean;
|
||||
loading: boolean;
|
||||
onClose: () => void;
|
||||
onCollabCancelClick: () => void;
|
||||
peerAskedCancel: boolean;
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
DialogContentText,
|
||||
Button,
|
||||
} from '@mui/material';
|
||||
import { Order } from '../../../models';
|
||||
import { type Order } from '../../../models';
|
||||
import currencies from '../../../../static/assets/currencies.json';
|
||||
import { pn } from '../../../utils';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
DialogContentText,
|
||||
Button,
|
||||
} from '@mui/material';
|
||||
import { Order } from '../../../models';
|
||||
import { type Order } from '../../../models';
|
||||
import currencies from '../../../../static/assets/currencies.json';
|
||||
import { pn } from '../../../utils';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
DialogContentText,
|
||||
Button,
|
||||
} from '@mui/material';
|
||||
import { Order } from '../../../models';
|
||||
import { type Order } from '../../../models';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
|
||||
interface ConfirmUndoFiatSentDialogProps {
|
||||
@ -30,7 +30,9 @@ export const ConfirmUndoFiatSentDialog = ({
|
||||
|
||||
useEffect(() => {
|
||||
if (time > 0 && open) {
|
||||
setTimeout(() => setTime(time - 1), 1000);
|
||||
setTimeout(() => {
|
||||
setTime(time - 1);
|
||||
}, 1000);
|
||||
}
|
||||
}, [time, open]);
|
||||
|
||||
|
@ -34,7 +34,14 @@ const ChatBottom: React.FC<Props> = ({ orderId, setAudit, audit, createJsonFile
|
||||
enterNextDelay={2000}
|
||||
title={t('Verify your privacy')}
|
||||
>
|
||||
<Button size='small' color='primary' variant='outlined' onClick={() => setAudit(!audit)}>
|
||||
<Button
|
||||
size='small'
|
||||
color='primary'
|
||||
variant='outlined'
|
||||
onClick={() => {
|
||||
setAudit(!audit);
|
||||
}}
|
||||
>
|
||||
<KeyIcon sx={{ width: '0.8em', height: '0.8em' }} />
|
||||
{t('Audit PGP')}{' '}
|
||||
</Button>
|
||||
@ -54,7 +61,9 @@ const ChatBottom: React.FC<Props> = ({ orderId, setAudit, audit, createJsonFile
|
||||
size='small'
|
||||
color='primary'
|
||||
variant='outlined'
|
||||
onClick={() => saveAsJson('complete_log_chat_' + orderId + '.json', createJsonFile())}
|
||||
onClick={() => {
|
||||
saveAsJson('complete_log_chat_' + orderId + '.json', createJsonFile());
|
||||
}}
|
||||
>
|
||||
<div style={{ width: '1.4em', height: '1.4em' }}>
|
||||
<ExportIcon sx={{ width: '0.8em', height: '0.8em' }} />
|
||||
@ -68,7 +77,9 @@ const ChatBottom: React.FC<Props> = ({ orderId, setAudit, audit, createJsonFile
|
||||
size='small'
|
||||
color='primary'
|
||||
variant='outlined'
|
||||
onClick={() => systemClient.copyToClipboard(JSON.stringify(createJsonFile()))}
|
||||
onClick={() => {
|
||||
systemClient.copyToClipboard(JSON.stringify(createJsonFile()));
|
||||
}}
|
||||
>
|
||||
<div style={{ width: '1.4em', height: '1.4em' }}>
|
||||
<ExportIcon sx={{ width: '0.8em', height: '0.8em' }} />
|
||||
|
@ -53,7 +53,9 @@ const ChatHeader: React.FC<Props> = ({ connected, peerConnected, turtleMode, set
|
||||
<IconButton
|
||||
size='small'
|
||||
color={turtleMode ? 'primary' : 'inherit'}
|
||||
onClick={() => setTurtleMode(!turtleMode)}
|
||||
onClick={() => {
|
||||
setTurtleMode(!turtleMode);
|
||||
}}
|
||||
>
|
||||
<WifiTetheringError />
|
||||
</IconButton>
|
||||
|
@ -3,8 +3,8 @@ import { useTranslation } from 'react-i18next';
|
||||
import { Button, Tooltip, TextField, Grid, Paper, Typography } from '@mui/material';
|
||||
import { encryptMessage, decryptMessage } from '../../../../pgp';
|
||||
import { AuditPGPDialog } from '../../../Dialogs';
|
||||
import { websocketClient, WebsocketConnection } from '../../../../services/Websocket';
|
||||
import { Robot } from '../../../../models';
|
||||
import { websocketClient, type WebsocketConnection } from '../../../../services/Websocket';
|
||||
import { type Robot } from '../../../../models';
|
||||
|
||||
// Icons
|
||||
import CircularProgress from '@mui/material/CircularProgress';
|
||||
@ -12,7 +12,7 @@ import KeyIcon from '@mui/icons-material/Key';
|
||||
import { useTheme } from '@mui/system';
|
||||
import MessageCard from '../MessageCard';
|
||||
import ChatHeader from '../ChatHeader';
|
||||
import { EncryptedChatMessage, ServerMessage } from '..';
|
||||
import { type EncryptedChatMessage, type ServerMessage } from '..';
|
||||
import ChatBottom from '../ChatBottom';
|
||||
import { sha256 } from 'js-sha256';
|
||||
|
||||
@ -107,9 +107,15 @@ const EncryptedSocketChat: React.FC<Props> = ({
|
||||
nick: userNick,
|
||||
});
|
||||
|
||||
connection.onMessage((message) => setServerMessages((prev) => [...prev, message]));
|
||||
connection.onClose(() => setConnected(false));
|
||||
connection.onError(() => setConnected(false));
|
||||
connection.onMessage((message) => {
|
||||
setServerMessages((prev) => [...prev, message]);
|
||||
});
|
||||
connection.onClose(() => {
|
||||
setConnected(false);
|
||||
});
|
||||
connection.onError(() => {
|
||||
setConnected(false);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@ -230,7 +236,9 @@ const EncryptedSocketChat: React.FC<Props> = ({
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => setError(error.toString()));
|
||||
.catch((error) => {
|
||||
setError(error.toString());
|
||||
});
|
||||
}
|
||||
e.preventDefault();
|
||||
};
|
||||
@ -245,14 +253,18 @@ const EncryptedSocketChat: React.FC<Props> = ({
|
||||
>
|
||||
<AuditPGPDialog
|
||||
open={audit}
|
||||
onClose={() => setAudit(false)}
|
||||
onClose={() => {
|
||||
setAudit(false);
|
||||
}}
|
||||
orderId={Number(orderId)}
|
||||
messages={messages}
|
||||
own_pub_key={robot.pubKey || ''}
|
||||
own_enc_priv_key={robot.encPrivKey || ''}
|
||||
peer_pub_key={peerPubKey || 'Not received yet'}
|
||||
passphrase={robot.token || ''}
|
||||
onClickBack={() => setAudit(false)}
|
||||
onClickBack={() => {
|
||||
setAudit(false);
|
||||
}}
|
||||
/>
|
||||
<Grid item>
|
||||
<ChatHeader
|
||||
|
@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next';
|
||||
import { Button, TextField, Grid, Paper, Typography } from '@mui/material';
|
||||
import { encryptMessage, decryptMessage } from '../../../../pgp';
|
||||
import { AuditPGPDialog } from '../../../Dialogs';
|
||||
import { Robot } from '../../../../models';
|
||||
import { type Robot } from '../../../../models';
|
||||
|
||||
// Icons
|
||||
import CircularProgress from '@mui/material/CircularProgress';
|
||||
@ -11,7 +11,7 @@ import KeyIcon from '@mui/icons-material/Key';
|
||||
import { useTheme } from '@mui/system';
|
||||
import MessageCard from '../MessageCard';
|
||||
import ChatHeader from '../ChatHeader';
|
||||
import { EncryptedChatMessage, ServerMessage } from '..';
|
||||
import { type EncryptedChatMessage, type ServerMessage } from '..';
|
||||
import { apiClient } from '../../../../services/api';
|
||||
import ChatBottom from '../ChatBottom';
|
||||
|
||||
@ -222,7 +222,9 @@ const EncryptedTurtleChat: React.FC<Props> = ({
|
||||
setValue('');
|
||||
});
|
||||
})
|
||||
.catch((error) => setError(error.toString()));
|
||||
.catch((error) => {
|
||||
setError(error.toString());
|
||||
});
|
||||
}
|
||||
e.preventDefault();
|
||||
};
|
||||
@ -237,14 +239,18 @@ const EncryptedTurtleChat: React.FC<Props> = ({
|
||||
>
|
||||
<AuditPGPDialog
|
||||
open={audit}
|
||||
onClose={() => setAudit(false)}
|
||||
onClose={() => {
|
||||
setAudit(false);
|
||||
}}
|
||||
orderId={Number(orderId)}
|
||||
messages={messages}
|
||||
own_pub_key={robot.pubKey || ''}
|
||||
own_enc_priv_key={robot.encPrivKey || ''}
|
||||
peer_pub_key={peerPubKey || 'Not received yet'}
|
||||
passphrase={robot.token || ''}
|
||||
onClickBack={() => setAudit(false)}
|
||||
onClickBack={() => {
|
||||
setAudit(false);
|
||||
}}
|
||||
/>
|
||||
|
||||
<Grid item>
|
||||
|
@ -9,7 +9,7 @@ import CheckIcon from '@mui/icons-material/Check';
|
||||
import CloseIcon from '@mui/icons-material/Close';
|
||||
import ContentCopy from '@mui/icons-material/ContentCopy';
|
||||
import VisibilityIcon from '@mui/icons-material/Visibility';
|
||||
import { EncryptedChatMessage } from '..';
|
||||
import { type EncryptedChatMessage } from '..';
|
||||
|
||||
interface Props {
|
||||
message: EncryptedChatMessage;
|
||||
@ -81,7 +81,9 @@ const MessageCard: React.FC<Props> = ({ message, isTaker, userConnected, baseUrl
|
||||
<div style={{ width: '1.4em' }}>
|
||||
<IconButton
|
||||
sx={{ height: '1.2em', width: '1.2em', position: 'relative', right: '0.15em' }}
|
||||
onClick={() => setShowPGP(!showPGP)}
|
||||
onClick={() => {
|
||||
setShowPGP(!showPGP);
|
||||
}}
|
||||
>
|
||||
<VisibilityIcon
|
||||
color={showPGP ? 'primary' : 'inherit'}
|
||||
@ -97,11 +99,11 @@ const MessageCard: React.FC<Props> = ({ message, isTaker, userConnected, baseUrl
|
||||
<Tooltip disableHoverListener enterTouchDelay={0} title={t('Copied!')}>
|
||||
<IconButton
|
||||
sx={{ height: '0.8em', width: '0.8em' }}
|
||||
onClick={() =>
|
||||
onClick={() => {
|
||||
systemClient.copyToClipboard(
|
||||
showPGP ? message.encryptedMessage : message.plainTextMessage,
|
||||
)
|
||||
}
|
||||
);
|
||||
}}
|
||||
>
|
||||
<ContentCopy
|
||||
sx={{
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Robot } from '../../../models';
|
||||
import { type Robot } from '../../../models';
|
||||
import EncryptedSocketChat from './EncryptedSocketChat';
|
||||
import EncryptedTurtleChat from './EncryptedTurtleChat';
|
||||
|
||||
|
@ -52,7 +52,9 @@ export const DisputeStatementForm = ({
|
||||
}}
|
||||
multiline
|
||||
rows={4}
|
||||
onChange={(e) => setDispute({ ...dispute, statement: e.target.value })}
|
||||
onChange={(e) => {
|
||||
setDispute({ ...dispute, statement: e.target.value });
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
@ -67,7 +69,9 @@ export const DisputeStatementForm = ({
|
||||
control={
|
||||
<Checkbox
|
||||
checked={dispute.attachLogs}
|
||||
onChange={() => setDispute({ ...dispute, attachLogs: !dispute.attachLogs })}
|
||||
onChange={() => {
|
||||
setDispute({ ...dispute, attachLogs: !dispute.attachLogs });
|
||||
}}
|
||||
/>
|
||||
}
|
||||
label={t('Attach chat logs')}
|
||||
|
@ -21,7 +21,7 @@ import {
|
||||
FormHelperText,
|
||||
} from '@mui/material';
|
||||
|
||||
import { Order, Settings } from '../../../models';
|
||||
import { type Order, type Settings } from '../../../models';
|
||||
import { decode } from 'light-bolt11-decoder';
|
||||
import WalletsButton from '../WalletsButton';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
@ -195,7 +195,9 @@ export const LightningPayoutForm = ({
|
||||
.catch(() => {
|
||||
setLightning({ ...lightning, badLnproxy: 'Lnproxy server uncaught error' });
|
||||
})
|
||||
.finally(() => setLoadingLnproxy(false));
|
||||
.finally(() => {
|
||||
setLoadingLnproxy(false);
|
||||
});
|
||||
};
|
||||
|
||||
const handleAdvancedOptions = function (checked: boolean) {
|
||||
@ -291,7 +293,9 @@ export const LightningPayoutForm = ({
|
||||
<Switch
|
||||
size='small'
|
||||
checked={lightning.advancedOptions}
|
||||
onChange={(e) => handleAdvancedOptions(e.target.checked)}
|
||||
onChange={(e) => {
|
||||
handleAdvancedOptions(e.target.checked);
|
||||
}}
|
||||
/>
|
||||
<SelfImprovement sx={{ color: 'text.primary' }} />
|
||||
</Grid>
|
||||
@ -375,13 +379,13 @@ export const LightningPayoutForm = ({
|
||||
>
|
||||
<div>
|
||||
<FormControlLabel
|
||||
onChange={(e) =>
|
||||
onChange={(e) => {
|
||||
setLightning({
|
||||
...lightning,
|
||||
useLnproxy: e.target.checked,
|
||||
invoice: e.target.checked ? '' : lightning.invoice,
|
||||
})
|
||||
}
|
||||
});
|
||||
}}
|
||||
checked={lightning.useLnproxy}
|
||||
control={<Checkbox />}
|
||||
label={
|
||||
@ -419,9 +423,9 @@ export const LightningPayoutForm = ({
|
||||
label={t('Server')}
|
||||
labelId='select-label'
|
||||
value={lightning.lnproxyServer}
|
||||
onChange={(e) =>
|
||||
setLightning({ ...lightning, lnproxyServer: Number(e.target.value) })
|
||||
}
|
||||
onChange={(e) => {
|
||||
setLightning({ ...lightning, lnproxyServer: Number(e.target.value) });
|
||||
}}
|
||||
>
|
||||
{lnproxies.map((lnproxyServer, index) => (
|
||||
<MenuItem key={index} value={index}>
|
||||
@ -494,13 +498,13 @@ export const LightningPayoutForm = ({
|
||||
<Tooltip disableHoverListener enterTouchDelay={0} title={t('Copied!')}>
|
||||
<IconButton
|
||||
sx={{ height: '0.5em' }}
|
||||
onClick={() =>
|
||||
onClick={() => {
|
||||
systemClient.copyToClipboard(
|
||||
lightning.useLnproxy
|
||||
? String(lightning.lnproxyAmount)
|
||||
: String(lightning.amount),
|
||||
)
|
||||
}
|
||||
);
|
||||
}}
|
||||
>
|
||||
<ContentCopy sx={{ width: '0.8em' }} />
|
||||
</IconButton>
|
||||
@ -523,9 +527,9 @@ export const LightningPayoutForm = ({
|
||||
style: { textAlign: 'center' },
|
||||
}}
|
||||
variant='outlined'
|
||||
onChange={(e) =>
|
||||
setLightning({ ...lightning, lnproxyInvoice: e.target.value ?? '' })
|
||||
}
|
||||
onChange={(e) => {
|
||||
setLightning({ ...lightning, lnproxyInvoice: e.target.value ?? '' });
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
@ -547,7 +551,9 @@ export const LightningPayoutForm = ({
|
||||
multiline={!lightning.useLnproxy}
|
||||
minRows={3}
|
||||
maxRows={5}
|
||||
onChange={(e) => setLightning({ ...lightning, invoice: e.target.value ?? '' })}
|
||||
onChange={(e) => {
|
||||
setLightning({ ...lightning, invoice: e.target.value ?? '' });
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
@ -572,7 +578,9 @@ export const LightningPayoutForm = ({
|
||||
<LoadingButton
|
||||
loading={loading}
|
||||
disabled={lightning.invoice.length < 20 || lightning.badInvoice != ''}
|
||||
onClick={() => onClickSubmit(lightning.invoice)}
|
||||
onClick={() => {
|
||||
onClickSubmit(lightning.invoice);
|
||||
}}
|
||||
variant='outlined'
|
||||
color='primary'
|
||||
>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Grid, Typography, TextField, List, Divider, ListItemText, ListItem } from '@mui/material';
|
||||
import { Order } from '../../../models';
|
||||
import { type Order } from '../../../models';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
import { pn } from '../../../utils';
|
||||
|
||||
@ -124,7 +124,9 @@ export const OnchainPayoutForm = ({
|
||||
inputProps={{
|
||||
style: { textAlign: 'center' },
|
||||
}}
|
||||
onChange={(e) => setOnchain({ ...onchain, address: e.target.value })}
|
||||
onChange={(e) => {
|
||||
setOnchain({ ...onchain, address: e.target.value });
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={5}>
|
||||
|
@ -3,9 +3,9 @@ import { useTranslation } from 'react-i18next';
|
||||
import { Grid, Typography, Tooltip, Collapse, IconButton } from '@mui/material';
|
||||
import currencies from '../../../../static/assets/currencies.json';
|
||||
|
||||
import { Order, Robot } from '../../../models';
|
||||
import { type Order, type Robot } from '../../../models';
|
||||
import { pn } from '../../../utils';
|
||||
import EncryptedChat, { EncryptedChatMessage } from '../EncryptedChat';
|
||||
import EncryptedChat, { type EncryptedChatMessage } from '../EncryptedChat';
|
||||
import Countdown, { zeroPad } from 'react-countdown';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Grid, Typography } from '@mui/material';
|
||||
import { DisputeForm, DisputeStatementForm } from '../Forms';
|
||||
import { type DisputeForm, DisputeStatementForm } from '../Forms';
|
||||
|
||||
interface DisputePromptProps {
|
||||
loading: boolean;
|
||||
|
@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next';
|
||||
import { Grid, Typography } from '@mui/material';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
|
||||
import { Order } from '../../../models';
|
||||
import { type Order } from '../../../models';
|
||||
|
||||
interface ExpiredPromptProps {
|
||||
order: Order;
|
||||
|
@ -3,11 +3,11 @@ import { useTranslation } from 'react-i18next';
|
||||
import { Button, Box, Grid, Typography, TextField, Tooltip, useTheme } from '@mui/material';
|
||||
import { ContentCopy } from '@mui/icons-material';
|
||||
import QRCode from 'react-qr-code';
|
||||
import { Order } from '../../../models';
|
||||
import { type Order } from '../../../models';
|
||||
import { systemClient } from '../../../services/System';
|
||||
import currencies from '../../../../static/assets/currencies.json';
|
||||
import WalletsButton from '../WalletsButton';
|
||||
import { AppContext, UseAppStoreType } from '../../../contexts/AppContext';
|
||||
import { AppContext, type UseAppStoreType } from '../../../contexts/AppContext';
|
||||
|
||||
interface LockInvoicePromptProps {
|
||||
order: Order;
|
||||
|
@ -4,10 +4,15 @@ import { Grid, Typography, ToggleButtonGroup, ToggleButton } from '@mui/material
|
||||
|
||||
import currencies from '../../../../static/assets/currencies.json';
|
||||
|
||||
import { Order, Settings } from '../../../models';
|
||||
import { type Order, type Settings } from '../../../models';
|
||||
import { pn } from '../../../utils';
|
||||
import { Bolt, Link } from '@mui/icons-material';
|
||||
import { LightningPayoutForm, LightningForm, OnchainPayoutForm, OnchainForm } from '../Forms';
|
||||
import {
|
||||
LightningPayoutForm,
|
||||
type LightningForm,
|
||||
OnchainPayoutForm,
|
||||
type OnchainForm,
|
||||
} from '../Forms';
|
||||
|
||||
interface PayoutPrompProps {
|
||||
order: Order;
|
||||
@ -71,7 +76,9 @@ export const PayoutPrompt = ({
|
||||
size='small'
|
||||
value={tab}
|
||||
exclusive
|
||||
onChange={(mouseEvent, value) => setTab(value == null ? tab : value)}
|
||||
onChange={(mouseEvent, value) => {
|
||||
setTab(value == null ? tab : value);
|
||||
}}
|
||||
>
|
||||
<ToggleButton value='lightning'>
|
||||
<div
|
||||
|
@ -14,7 +14,7 @@ import { LoadingButton } from '@mui/lab';
|
||||
|
||||
import currencies from '../../../../static/assets/currencies.json';
|
||||
|
||||
import { Order } from '../../../models';
|
||||
import { type Order } from '../../../models';
|
||||
import { PauseCircle, Storefront, Percent } from '@mui/icons-material';
|
||||
|
||||
interface PublicWaitPrompProps {
|
||||
|
@ -1,10 +1,10 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Box, CircularProgress, Grid, Typography, useTheme } from '@mui/material';
|
||||
import Countdown, { CountdownRenderProps, zeroPad } from 'react-countdown';
|
||||
import Countdown, { type CountdownRenderProps, zeroPad } from 'react-countdown';
|
||||
|
||||
import { Order, Settings } from '../../../models';
|
||||
import { LightningForm, LightningPayoutForm } from '../Forms';
|
||||
import { type Order, type Settings } from '../../../models';
|
||||
import { type LightningForm, LightningPayoutForm } from '../Forms';
|
||||
|
||||
interface RoutingFailedPromptProps {
|
||||
order: Order;
|
||||
|
@ -18,7 +18,7 @@ import TradeSummary from '../TradeSummary';
|
||||
import { Favorite, RocketLaunch, ContentCopy, Refresh } from '@mui/icons-material';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
|
||||
import { Order } from '../../../models';
|
||||
import { type Order } from '../../../models';
|
||||
import { systemClient } from '../../../services/System';
|
||||
|
||||
interface SuccessfulPromptProps {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Typography, useTheme } from '@mui/material';
|
||||
import { Order } from '../../../models';
|
||||
import { type Order } from '../../../models';
|
||||
import stepXofY from '../stepXofY';
|
||||
|
||||
interface TakerFoundPrompProps {
|
||||
|
@ -30,7 +30,7 @@ import {
|
||||
Link,
|
||||
} from '@mui/icons-material';
|
||||
import { RoboSatsNoTextIcon, SendReceiveIcon, BitcoinIcon } from '../Icons';
|
||||
import { TradeCoordinatorSummary, TradeRobotSummary } from '../../models/Order.model';
|
||||
import { type TradeCoordinatorSummary, type TradeRobotSummary } from '../../models/Order.model';
|
||||
import { systemClient } from '../../services/System';
|
||||
|
||||
interface Props {
|
||||
@ -110,7 +110,13 @@ const TradeSummary = ({
|
||||
}}
|
||||
>
|
||||
<ToggleButtonGroup size='small' value={buttonValue} exclusive>
|
||||
<ToggleButton value={0} disableRipple={true} onClick={() => setButtonValue(0)}>
|
||||
<ToggleButton
|
||||
value={0}
|
||||
disableRipple={true}
|
||||
onClick={() => {
|
||||
setButtonValue(0);
|
||||
}}
|
||||
>
|
||||
<RobotAvatar
|
||||
baseUrl={baseUrl}
|
||||
style={{ height: '1.5em', width: '1.5em' }}
|
||||
@ -120,10 +126,22 @@ const TradeSummary = ({
|
||||
|
||||
{t('Maker')}
|
||||
</ToggleButton>
|
||||
<ToggleButton value={1} disableRipple={true} onClick={() => setButtonValue(1)}>
|
||||
<ToggleButton
|
||||
value={1}
|
||||
disableRipple={true}
|
||||
onClick={() => {
|
||||
setButtonValue(1);
|
||||
}}
|
||||
>
|
||||
<RoboSatsNoTextIcon />
|
||||
</ToggleButton>
|
||||
<ToggleButton value={2} disableRipple={true} onClick={() => setButtonValue(2)}>
|
||||
<ToggleButton
|
||||
value={2}
|
||||
disableRipple={true}
|
||||
onClick={() => {
|
||||
setButtonValue(2);
|
||||
}}
|
||||
>
|
||||
{t('Taker')}
|
||||
|
||||
<RobotAvatar
|
||||
|
@ -39,15 +39,15 @@ import BondStatus from './BondStatus';
|
||||
import CancelButton from './CancelButton';
|
||||
import {
|
||||
defaultLightning,
|
||||
LightningForm,
|
||||
type LightningForm,
|
||||
defaultOnchain,
|
||||
OnchainForm,
|
||||
DisputeForm,
|
||||
type OnchainForm,
|
||||
type DisputeForm,
|
||||
defaultDispute,
|
||||
} from './Forms';
|
||||
|
||||
import { Order, Robot, Settings } from '../../models';
|
||||
import { EncryptedChatMessage } from './EncryptedChat';
|
||||
import { type Order, type Robot, type Settings } from '../../models';
|
||||
import { type EncryptedChatMessage } from './EncryptedChat';
|
||||
import CollabCancelAlert from './CollabCancelAlert';
|
||||
import { Bolt } from '@mui/icons-material';
|
||||
|
||||
@ -259,7 +259,9 @@ const TradeBox = ({
|
||||
};
|
||||
|
||||
const handleWebln = async (order: Order) => {
|
||||
const webln = await getWebln().catch(() => console.log('WebLN not available'));
|
||||
const webln = await getWebln().catch(() => {
|
||||
console.log('WebLN not available');
|
||||
});
|
||||
// If Webln implements locked payments compatibility, this logic might be simplier
|
||||
if (webln == undefined) {
|
||||
return null;
|
||||
@ -488,13 +490,21 @@ const TradeBox = ({
|
||||
<ChatPrompt
|
||||
order={order}
|
||||
robot={robot}
|
||||
onClickConfirmSent={() => setOpen({ ...open, confirmFiatSent: true })}
|
||||
onClickUndoConfirmSent={() => setOpen({ ...open, confirmUndoFiatSent: true })}
|
||||
onClickConfirmReceived={() => setOpen({ ...open, confirmFiatReceived: true })}
|
||||
onClickConfirmSent={() => {
|
||||
setOpen({ ...open, confirmFiatSent: true });
|
||||
}}
|
||||
onClickUndoConfirmSent={() => {
|
||||
setOpen({ ...open, confirmUndoFiatSent: true });
|
||||
}}
|
||||
onClickConfirmReceived={() => {
|
||||
setOpen({ ...open, confirmFiatReceived: true });
|
||||
}}
|
||||
loadingSent={loadingButtons.fiatSent}
|
||||
loadingUndoSent={loadingButtons.undoFiatSent}
|
||||
loadingReceived={loadingButtons.fiatReceived}
|
||||
onClickDispute={() => setOpen({ ...open, confirmDispute: true })}
|
||||
onClickDispute={() => {
|
||||
setOpen({ ...open, confirmDispute: true });
|
||||
}}
|
||||
loadingDispute={loadingButtons.openDispute}
|
||||
baseUrl={baseUrl}
|
||||
messages={messages}
|
||||
@ -668,23 +678,31 @@ const TradeBox = ({
|
||||
<Box>
|
||||
<WebLNDialog
|
||||
open={open.webln}
|
||||
onClose={() => setOpen(closeAll)}
|
||||
onClose={() => {
|
||||
setOpen(closeAll);
|
||||
}}
|
||||
waitingWebln={waitingWebln}
|
||||
isBuyer={order.is_buyer}
|
||||
/>
|
||||
<ConfirmDisputeDialog
|
||||
open={open.confirmDispute}
|
||||
onClose={() => setOpen(closeAll)}
|
||||
onClose={() => {
|
||||
setOpen(closeAll);
|
||||
}}
|
||||
onAgreeClick={openDispute}
|
||||
/>
|
||||
<ConfirmCancelDialog
|
||||
open={open.confirmCancel}
|
||||
onClose={() => setOpen(closeAll)}
|
||||
onClose={() => {
|
||||
setOpen(closeAll);
|
||||
}}
|
||||
onCancelClick={cancel}
|
||||
/>
|
||||
<ConfirmCollabCancelDialog
|
||||
open={open.confirmCollabCancel}
|
||||
onClose={() => setOpen(closeAll)}
|
||||
onClose={() => {
|
||||
setOpen(closeAll);
|
||||
}}
|
||||
onCollabCancelClick={cancel}
|
||||
loading={loadingButtons.cancel}
|
||||
peerAskedCancel={order.pending_cancel}
|
||||
@ -693,21 +711,27 @@ const TradeBox = ({
|
||||
open={open.confirmFiatSent}
|
||||
order={order}
|
||||
loadingButton={loadingButtons.fiatSent}
|
||||
onClose={() => setOpen(closeAll)}
|
||||
onClose={() => {
|
||||
setOpen(closeAll);
|
||||
}}
|
||||
onConfirmClick={confirmFiatSent}
|
||||
/>
|
||||
<ConfirmUndoFiatSentDialog
|
||||
open={open.confirmUndoFiatSent}
|
||||
order={order}
|
||||
loadingButton={loadingButtons.undoFiatSent}
|
||||
onClose={() => setOpen(closeAll)}
|
||||
onClose={() => {
|
||||
setOpen(closeAll);
|
||||
}}
|
||||
onConfirmClick={confirmUndoFiatSent}
|
||||
/>
|
||||
<ConfirmFiatReceivedDialog
|
||||
open={open.confirmFiatReceived}
|
||||
order={order}
|
||||
loadingButton={loadingButtons.fiatReceived}
|
||||
onClose={() => setOpen(closeAll)}
|
||||
onClose={() => {
|
||||
setOpen(closeAll);
|
||||
}}
|
||||
onConfirmClick={confirmFiatReceived}
|
||||
/>
|
||||
<CollabCancelAlert order={order} />
|
||||
@ -745,8 +769,12 @@ const TradeBox = ({
|
||||
<CancelButton
|
||||
order={order}
|
||||
onClickCancel={cancel}
|
||||
openCancelDialog={() => setOpen({ ...closeAll, confirmCancel: true })}
|
||||
openCollabCancelDialog={() => setOpen({ ...closeAll, confirmCollabCancel: true })}
|
||||
openCancelDialog={() => {
|
||||
setOpen({ ...closeAll, confirmCancel: true });
|
||||
}}
|
||||
openCollabCancelDialog={() => {
|
||||
setOpen({ ...closeAll, confirmCollabCancel: true });
|
||||
}}
|
||||
loading={loadingButtons.cancel}
|
||||
/>
|
||||
</Grid>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Order } from '../../models';
|
||||
import { type Order } from '../../models';
|
||||
|
||||
const stepXofY = function (order: Order): string {
|
||||
// set y value
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useState, useEffect, useContext } from 'react';
|
||||
import { AppContext, UseAppStoreType } from '../contexts/AppContext';
|
||||
import { AppContext, type UseAppStoreType } from '../contexts/AppContext';
|
||||
import { useTranslation, Trans } from 'react-i18next';
|
||||
import { Paper, Alert, AlertTitle, Button, Link } from '@mui/material';
|
||||
import { getHost } from '../utils';
|
||||
@ -57,7 +57,12 @@ const UnsafeAlert = (): JSX.Element => {
|
||||
severity='success'
|
||||
sx={{ maxHeight: '8em' }}
|
||||
action={
|
||||
<Button color='success' onClick={() => setShow(false)}>
|
||||
<Button
|
||||
color='success'
|
||||
onClick={() => {
|
||||
setShow(false);
|
||||
}}
|
||||
>
|
||||
{t('Hide')}
|
||||
</Button>
|
||||
}
|
||||
@ -80,7 +85,15 @@ const UnsafeAlert = (): JSX.Element => {
|
||||
<Alert
|
||||
severity='warning'
|
||||
sx={{ maxHeight: '7em' }}
|
||||
action={<Button onClick={() => setShow(false)}>{t('Hide')}</Button>}
|
||||
action={
|
||||
<Button
|
||||
onClick={() => {
|
||||
setShow(false);
|
||||
}}
|
||||
>
|
||||
{t('Hide')}
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<AlertTitle>{t('You are not using RoboSats privately')}</AlertTitle>
|
||||
<Trans i18nKey='desktop_unsafe_alert'>
|
||||
@ -120,7 +133,12 @@ const UnsafeAlert = (): JSX.Element => {
|
||||
<a> site.</a>
|
||||
</Trans>
|
||||
<div style={{ display: 'flex', justifyContent: 'center', width: '100%' }}>
|
||||
<Button className='hideAlertButton' onClick={() => setShow(false)}>
|
||||
<Button
|
||||
className='hideAlertButton'
|
||||
onClick={() => {
|
||||
setShow(false);
|
||||
}}
|
||||
>
|
||||
{t('Hide')}
|
||||
</Button>
|
||||
</div>
|
||||
|
@ -1,20 +1,20 @@
|
||||
import React, { createContext, useEffect, useState } from 'react';
|
||||
import { Page } from '../basic/NavBar';
|
||||
import { OpenDialogs } from '../basic/MainDialogs';
|
||||
import { type Page } from '../basic/NavBar';
|
||||
import { type OpenDialogs } from '../basic/MainDialogs';
|
||||
|
||||
import {
|
||||
Book,
|
||||
LimitList,
|
||||
Maker,
|
||||
type Book,
|
||||
type LimitList,
|
||||
type Maker,
|
||||
Robot,
|
||||
Garage,
|
||||
Info,
|
||||
type Info,
|
||||
Settings,
|
||||
Favorites,
|
||||
type Favorites,
|
||||
defaultMaker,
|
||||
defaultInfo,
|
||||
Coordinator,
|
||||
Order,
|
||||
type Coordinator,
|
||||
type Order,
|
||||
} from '../models';
|
||||
|
||||
import { apiClient } from '../services/api';
|
||||
@ -22,7 +22,7 @@ import { checkVer, getHost, hexToBase91, validateTokenEntropy } from '../utils';
|
||||
import { sha256 } from 'js-sha256';
|
||||
|
||||
import defaultCoordinators from '../../static/federation.json';
|
||||
import { createTheme, Theme } from '@mui/material/styles';
|
||||
import { createTheme, type Theme } from '@mui/material/styles';
|
||||
import i18n from '../i18n/Web';
|
||||
import { systemClient } from '../services/System';
|
||||
|
||||
@ -163,7 +163,12 @@ export const useAppStore = () => {
|
||||
useEffect(() => {
|
||||
window.addEventListener('torStatus', (event) => {
|
||||
// Trick to improve UX on Android webview: delay the "Connected to TOR" status by 5 secs to avoid long waits on the first request.
|
||||
setTimeout(() => setTorStatus(event?.detail), event?.detail === '"Done"' ? 5000 : 0);
|
||||
setTimeout(
|
||||
() => {
|
||||
setTorStatus(event?.detail);
|
||||
},
|
||||
event?.detail === '"Done"' ? 5000 : 0,
|
||||
);
|
||||
});
|
||||
}, []);
|
||||
|
||||
@ -213,12 +218,12 @@ export const useAppStore = () => {
|
||||
setBook((book) => {
|
||||
return { ...book, loading: true };
|
||||
});
|
||||
apiClient.get(baseUrl, '/api/book/').then((data: any) =>
|
||||
apiClient.get(baseUrl, '/api/book/').then((data: any) => {
|
||||
setBook({
|
||||
loading: false,
|
||||
orders: data.not_found ? [] : data,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const fetchLimits = async () => {
|
||||
@ -272,7 +277,9 @@ export const useAppStore = () => {
|
||||
useEffect(() => {
|
||||
clearInterval(timer);
|
||||
setTimer(setInterval(fetchOrder, delay));
|
||||
return () => clearInterval(timer);
|
||||
return () => {
|
||||
clearInterval(timer);
|
||||
};
|
||||
}, [delay, currentOrder, page, badOrder]);
|
||||
|
||||
const orderReceived = function (data: any) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Robot, Order } from '.';
|
||||
import { Robot, type Order } from '.';
|
||||
import { systemClient } from '../services/System';
|
||||
import { saveAsJson } from '../utils';
|
||||
export interface Slot {
|
||||
|
@ -6,8 +6,6 @@ export interface Limit {
|
||||
max_bondless_amount: number;
|
||||
}
|
||||
|
||||
export interface LimitList {
|
||||
[currencyCode: string]: Limit;
|
||||
}
|
||||
export type LimitList = Record<string, Limit>;
|
||||
|
||||
export default Limit;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useContext, useState } from 'react';
|
||||
import GridLayout, { Layout } from 'react-grid-layout';
|
||||
import GridLayout, { type Layout } from 'react-grid-layout';
|
||||
import { Grid, styled, useTheme } from '@mui/material';
|
||||
|
||||
import {
|
||||
@ -12,7 +12,7 @@ import {
|
||||
import ToolBar from '../pro/ToolBar';
|
||||
import LandingDialog from '../pro/LandingDialog';
|
||||
|
||||
import { AppContext, UseAppStoreType } from '../contexts/AppContext';
|
||||
import { AppContext, type UseAppStoreType } from '../contexts/AppContext';
|
||||
|
||||
// To Do. Add dotted grid when layout is not frozen
|
||||
// ${freeze ?
|
||||
@ -83,7 +83,12 @@ const Main = (): JSX.Element => {
|
||||
<Grid container direction='column' sx={{ width: `${windowSize.width}em` }}>
|
||||
<Grid item>
|
||||
<ToolBar height={`${toolbarHeight}em`} settings={settings} setSettings={setSettings} />
|
||||
<LandingDialog open={openLanding} onClose={() => setOpenLanding(!openLanding)} />
|
||||
<LandingDialog
|
||||
open={openLanding}
|
||||
onClose={() => {
|
||||
setOpenLanding(!openLanding);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<Grid item>
|
||||
@ -101,7 +106,9 @@ const Main = (): JSX.Element => {
|
||||
isResizable={!settings.freezeViewports}
|
||||
rowHeight={gridCellSize * em} // rows are 2em high
|
||||
autoSize={true}
|
||||
onLayoutChange={(layout: Layout) => setLayout(layout)}
|
||||
onLayoutChange={(layout: Layout) => {
|
||||
setLayout(layout);
|
||||
}}
|
||||
>
|
||||
<div key='Maker'>
|
||||
<MakerWidget />
|
||||
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { Paper, Grid, IconButton, Tooltip, Typography } from '@mui/material';
|
||||
import { Lock, LockOpen } from '@mui/icons-material';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Settings } from '../../models';
|
||||
import { type Settings } from '../../models';
|
||||
|
||||
interface ToolBarProps {
|
||||
settings: Settings;
|
||||
@ -39,9 +39,9 @@ const ToolBar = ({ height = '3em', settings, setSettings }: ToolBarProps): JSX.E
|
||||
enterNextDelay={2000}
|
||||
>
|
||||
<IconButton
|
||||
onClick={() =>
|
||||
setSettings({ ...settings, freezeViewports: !settings.freezeViewports })
|
||||
}
|
||||
onClick={() => {
|
||||
setSettings({ ...settings, freezeViewports: !settings.freezeViewports });
|
||||
}}
|
||||
sx={{ position: 'fixed', right: '1em', top: '0em', color: 'text.secondary' }}
|
||||
>
|
||||
{settings.freezeViewports ? <Lock color='primary' /> : <LockOpen color='secondary' />}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
|
||||
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
|
||||
|
||||
import { Book, Favorites } from '../../models';
|
||||
import { type Book, type Favorites } from '../../models';
|
||||
import { Paper } from '@mui/material';
|
||||
import BookTable from '../../components/BookTable';
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
|
||||
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
|
||||
import { Paper, useTheme } from '@mui/material';
|
||||
import DepthChart from '../../components/Charts/DepthChart';
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
|
||||
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
|
||||
|
||||
import MakerForm from '../../components/MakerForm';
|
||||
import { LimitList, Maker, Favorites } from '../../models';
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { UseAppStoreType, AppContext } from '../../contexts/AppContext';
|
||||
import { type UseAppStoreType, AppContext } from '../../contexts/AppContext';
|
||||
import { Settings } from '../../models';
|
||||
import { Paper } from '@mui/material';
|
||||
import SettingsForm from '../../components/SettingsForm';
|
||||
|
2
frontend/src/services/Native/index.d.ts
vendored
2
frontend/src/services/Native/index.d.ts
vendored
@ -1,4 +1,4 @@
|
||||
import NativeRobosats from './index';
|
||||
import type NativeRobosats from './index';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
|
@ -1,13 +1,17 @@
|
||||
import { NativeRobosatsPromise, NativeWebViewMessage, NativeWebViewMessageSystem } from './index.d';
|
||||
import {
|
||||
type NativeRobosatsPromise,
|
||||
type NativeWebViewMessage,
|
||||
type NativeWebViewMessageSystem,
|
||||
} from './index.d';
|
||||
|
||||
class NativeRobosats {
|
||||
public torDaemonStatus = 'NOTINIT';
|
||||
|
||||
private messageCounter: number = 0;
|
||||
|
||||
private pendingMessages: { [id: number]: NativeRobosatsPromise } = {};
|
||||
private pendingMessages: Record<number, NativeRobosatsPromise> = {};
|
||||
|
||||
public cookies: { [key: string]: string } = {};
|
||||
public cookies: Record<string, string> = {};
|
||||
|
||||
public loadCookie = (cookie: { key: string; value: string }) => {
|
||||
this.cookies[cookie.key] = cookie.value;
|
||||
@ -44,7 +48,7 @@ class NativeRobosats {
|
||||
}
|
||||
};
|
||||
|
||||
public postMessage: (message: NativeWebViewMessage) => Promise<{ [key: string]: any }> = async (
|
||||
public postMessage: (message: NativeWebViewMessage) => Promise<Record<string, any>> = async (
|
||||
message,
|
||||
) => {
|
||||
this.messageCounter += 1;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { SystemClient } from '..';
|
||||
import { type SystemClient } from '..';
|
||||
import NativeRobosats from '../../Native';
|
||||
|
||||
class SystemNativeClient implements SystemClient {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { SystemClient } from '..';
|
||||
import { type SystemClient } from '..';
|
||||
|
||||
class SystemWebClient implements SystemClient {
|
||||
public loading = false;
|
||||
|
@ -1,12 +1,14 @@
|
||||
import ReconnectingWebSocket from 'reconnecting-websocket';
|
||||
import { WebsocketConnection } from '..';
|
||||
import { type WebsocketConnection } from '..';
|
||||
|
||||
class WebsocketConnectionWeb implements WebsocketConnection {
|
||||
constructor(path: string) {
|
||||
this.rws = new ReconnectingWebSocket(path, [], {
|
||||
WebSocket,
|
||||
minReconnectionDelay: 15000,
|
||||
connectionTimeout: 15000,
|
||||
reconnectionDelayGrowFactor: 1.5,
|
||||
maxRetries: 15,
|
||||
reconnectionDelayGrowFactor: 2,
|
||||
maxRetries: 4,
|
||||
maxReconnectionDelay: 1000000,
|
||||
});
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { WebsocketClient, WebsocketConnection } from '..';
|
||||
import { type WebsocketClient, type WebsocketConnection } from '..';
|
||||
import WebsocketConnectionWeb from '../WebsocketConnectionWeb';
|
||||
|
||||
class WebsocketWebClient implements WebsocketClient {
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { ApiClient, Auth } from '..';
|
||||
import { type ApiClient, type Auth } from '..';
|
||||
import { systemClient } from '../../System';
|
||||
|
||||
class ApiNativeClient implements ApiClient {
|
||||
private assetsCache: { [path: string]: string } = {};
|
||||
private assetsPromises: { [path: string]: Promise<string | undefined> } = {};
|
||||
private assetsCache: Record<string, string> = {};
|
||||
private assetsPromises: Record<string, Promise<string | undefined>> = {};
|
||||
|
||||
private readonly getHeaders: (auth?: Auth) => HeadersInit = (auth) => {
|
||||
let headers = {
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
|
||||
if (auth) {
|
||||
if (auth != null) {
|
||||
headers = {
|
||||
...headers,
|
||||
...{
|
||||
@ -19,7 +19,7 @@ class ApiNativeClient implements ApiClient {
|
||||
};
|
||||
}
|
||||
|
||||
if (auth?.keys) {
|
||||
if (auth?.keys != null) {
|
||||
headers = {
|
||||
...headers,
|
||||
...{
|
||||
@ -31,7 +31,7 @@ class ApiNativeClient implements ApiClient {
|
||||
return headers;
|
||||
};
|
||||
|
||||
private readonly parseResponse = (response: { [key: string]: any }): object => {
|
||||
private readonly parseResponse = (response: Record<string, any>): object => {
|
||||
if (response.headers['set-cookie']) {
|
||||
response.headers['set-cookie'].forEach((cookie: string) => {
|
||||
const keySplit: string[] = cookie.split('=');
|
||||
@ -46,7 +46,9 @@ class ApiNativeClient implements ApiClient {
|
||||
path,
|
||||
body,
|
||||
) => {
|
||||
return await new Promise((res, _rej) => res({}));
|
||||
return await new Promise((res, _rej) => {
|
||||
res({});
|
||||
});
|
||||
};
|
||||
|
||||
public delete: (baseUrl: string, path: string, auth?: Auth) => Promise<object | undefined> =
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { ApiClient, Auth } from '..';
|
||||
import { type ApiClient, type Auth } from '..';
|
||||
import { systemClient } from '../../System';
|
||||
|
||||
class ApiWebClient implements ApiClient {
|
||||
@ -7,7 +7,7 @@ class ApiWebClient implements ApiClient {
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
|
||||
if (auth) {
|
||||
if (auth != null) {
|
||||
headers = {
|
||||
...headers,
|
||||
...{
|
||||
@ -17,7 +17,7 @@ class ApiWebClient implements ApiClient {
|
||||
}
|
||||
|
||||
// set cookies before sending the request
|
||||
if (auth?.keys) {
|
||||
if (auth?.keys != null) {
|
||||
systemClient.setCookie('public_key', auth.keys.pubKey);
|
||||
systemClient.setCookie('encrypted_private_key', auth.keys.encPrivKey);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { PublicOrder, Favorites } from '../models';
|
||||
import { type PublicOrder, type Favorites } from '../models';
|
||||
|
||||
interface AmountFilter {
|
||||
amount: string;
|
||||
|
@ -2,7 +2,7 @@ import { Base91 } from 'base-ex';
|
||||
|
||||
export default function hexToBase85(hex: string): string {
|
||||
const hexes = hex.match(/.{1,2}/g);
|
||||
if (!hexes) return '';
|
||||
if (hexes == null) return '';
|
||||
const byteArray = hexes.map((byte) => parseInt(byte, 16));
|
||||
const b91 = new Base91();
|
||||
const base91string = b91.encode(new Uint8Array(byteArray));
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { requestProvider, WeblnProvider } from 'webln';
|
||||
import { requestProvider, type WeblnProvider } from 'webln';
|
||||
|
||||
const getWebln = async (): Promise<WeblnProvider> => {
|
||||
const resultPromise = new Promise<WeblnProvider>(async (resolve, reject) => {
|
||||
|
Loading…
Reference in New Issue
Block a user