Enhance UI for Swaps (#346)

* Add better fiat/swap UI switches

* Add swap controls to booktable

* Enhance order details and take button for swaps

* Add swap specific order summary strings

* Add specific bond commitment descriptions for swap orders

* Fix cosmetics
This commit is contained in:
Reckless_Satoshi 2023-02-10 13:28:26 +00:00 committed by GitHub
parent 237c9fd951
commit 965bbb0765
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 324 additions and 197 deletions

View File

@ -69,15 +69,6 @@ const BookPage = ({
}
}, []);
const handleCurrencyChange = function (e) {
const currency = e.target.value;
setFav({ ...fav, currency });
};
const handleTypeChange = function (mouseEvent, val) {
setFav({ ...fav, type: val });
};
const onOrderClicked = function (id: number) {
if (hasRobot) {
history.push('/order/' + id);
@ -159,13 +150,12 @@ const BookPage = ({
clickRefresh={() => fetchBook()}
book={book}
fav={fav}
setFav={setFav}
maxWidth={maxBookTableWidth} // EM units
maxHeight={windowSize.height * 0.825 - 5} // EM units
fullWidth={windowSize.width} // EM units
fullHeight={windowSize.height} // EM units
defaultFullscreen={false}
onCurrencyChange={handleCurrencyChange}
onTypeChange={handleTypeChange}
onOrderClicked={onOrderClicked}
baseUrl={baseUrl}
/>
@ -199,13 +189,12 @@ const BookPage = ({
book={book}
clickRefresh={() => fetchBook()}
fav={fav}
setFav={setFav}
maxWidth={windowSize.width * 0.97} // EM units
maxHeight={windowSize.height * 0.825 - 5} // EM units
fullWidth={windowSize.width} // EM units
fullHeight={windowSize.height} // EM units
defaultFullscreen={false}
onCurrencyChange={handleCurrencyChange}
onTypeChange={handleTypeChange}
onOrderClicked={onOrderClicked}
baseUrl={baseUrl}
/>

View File

@ -89,7 +89,7 @@ const Main = ({ settings, setSettings }: MainProps): JSX.Element => {
const [info, setInfo] = useState<Info>(defaultInfo);
const [coordinators, setCoordinators] = useState<Coordinator[]>(defaultCoordinators);
const [baseUrl, setBaseUrl] = useState<string>('');
const [fav, setFav] = useState<Favorites>({ type: null, currency: 0 });
const [fav, setFav] = useState<Favorites>({ type: null, mode: 'fiat', currency: 0 });
const [delay, setDelay] = useState<number>(60000);
const [timer, setTimer] = useState<NodeJS.Timer | undefined>(setInterval(() => null, delay));
@ -456,6 +456,8 @@ const Main = ({ settings, setSettings }: MainProps): JSX.Element => {
>
<div>
<SettingsPage
fav={fav}
setFav={setFav}
settings={settings}
setSettings={setSettings}
windowSize={{ ...windowSize, height: windowSize.height - navbarHeight }}

View File

@ -2,15 +2,23 @@ import React from 'react';
import { useTranslation } from 'react-i18next';
import { Grid, Paper, useTheme } from '@mui/material';
import SettingsForm from '../../components/SettingsForm';
import { Settings } from '../../models';
import { Settings, Favorites } from '../../models';
interface SettingsPageProps {
fav: Favorites;
setFav: (state: Favorites) => void;
settings: Settings;
setSettings: (state: Settings) => void;
windowSize: { width: number; height: number };
}
const SettingsPage = ({ settings, setSettings, windowSize }: SettingsPageProps): JSX.Element => {
const SettingsPage = ({
fav,
setFav,
settings,
setSettings,
windowSize,
}: SettingsPageProps): JSX.Element => {
const theme = useTheme();
const { t } = useTranslation();
const maxHeight = windowSize.height * 0.85 - 3;
@ -23,6 +31,8 @@ const SettingsPage = ({ settings, setSettings, windowSize }: SettingsPageProps):
<Grid container>
<Grid item>
<SettingsForm
fav={fav}
setFav={setFav}
settings={settings}
setSettings={setSettings}
showNetwork={!(window.NativeRobosats === undefined)}

View File

@ -9,6 +9,7 @@ import {
Divider,
MenuItem,
Box,
Tooltip,
} from '@mui/material';
import currencyDict from '../../../static/assets/currencies.json';
import { useTheme } from '@mui/system';
@ -17,34 +18,50 @@ import { fiatMethods, swapMethods, PaymentIcon } from '../PaymentMethods';
import { FlagWithProps } from '../Icons';
import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank';
import { Favorites } from '../../models';
import SwapCalls from '@mui/icons-material/SwapCalls';
interface BookControlProps {
width: number;
type: number;
currency: number;
fav: Favorites;
setFav: (state: Favorites) => void;
paymentMethod: string[];
onCurrencyChange: () => void;
onTypeChange: () => void;
setPaymentMethods: () => void;
}
const BookControl = ({
width,
type,
currency,
onCurrencyChange,
onTypeChange,
fav,
setFav,
paymentMethod,
setPaymentMethods,
}: BookControlProps): JSX.Element => {
const { t } = useTranslation();
const theme = useTheme();
const smallestToolbarWidth = (t('Buy').length + t('Sell').length) * 0.7 + 12;
const typeZeroText = fav.mode === 'fiat' ? 'Buy' : 'Swap In';
const typeOneText = fav.mode === 'fiat' ? 'Sell' : 'Swap Out';
const smallestToolbarWidth = (typeZeroText.length + typeOneText.length) * 0.7 + 12;
const mediumToolbarWidth = smallestToolbarWidth + 12;
const verboseToolbarWidth =
mediumToolbarWidth + (t('and use').length + t('pay with').length) * 0.6;
const handleCurrencyChange = function (e) {
const currency = e.target.value;
setFav({ ...fav, currency, mode: currency === 1000 ? 'swap' : 'fiat' });
};
const handleTypeChange = function (mouseEvent, val) {
setFav({ ...fav, type: val });
};
const handleModeChange = function (mouseEvent, val) {
const mode = fav.mode === 'fiat' ? 'swap' : 'fiat';
const currency = fav.mode === 'fiat' ? 1000 : 0;
setFav({ ...fav, mode, currency });
};
return (
<Box>
<Grid
@ -64,6 +81,13 @@ const BookControl = ({
) : null}
<Grid item>
<Tooltip
placement='bottom'
enterTouchDelay={200}
enterDelay={700}
enterNextDelay={2000}
title={t('Show Lightning swaps')}
>
<ToggleButtonGroup
sx={{
height: '2.6em',
@ -77,19 +101,43 @@ const BookControl = ({
}}
size='small'
exclusive={true}
value={type}
onChange={onTypeChange}
value={fav.mode}
onChange={handleModeChange}
>
<ToggleButton value={'swap'} color={'secondary'}>
<SwapCalls />
</ToggleButton>
</ToggleButtonGroup>
</Tooltip>
</Grid>
<Grid item>
<ToggleButtonGroup
sx={{
height: '2.6em',
backgroundColor: theme.palette.background.paper,
border: '0.5px solid',
borderColor: 'text.disabled',
'&:hover': {
borderColor: 'text.primary',
border: '1px solid',
},
}}
size='small'
exclusive={true}
value={fav.type}
onChange={handleTypeChange}
>
<ToggleButton value={1} color={'primary'}>
{t('Buy')}
{typeZeroText}
</ToggleButton>
<ToggleButton value={0} color={'secondary'}>
{t('Sell')}
{typeOneText}
</ToggleButton>
</ToggleButtonGroup>
</Grid>
{width > verboseToolbarWidth ? (
{width > verboseToolbarWidth && fav.mode === 'fiat' ? (
<Grid item sx={{ position: 'relative', top: '0.5em' }}>
<Typography variant='caption' color='text.secondary'>
{t('and use')}
@ -97,6 +145,7 @@ const BookControl = ({
</Grid>
) : null}
{fav.mode === 'fiat' ? (
<Grid item>
<Select
autoWidth
@ -113,11 +162,11 @@ const BookControl = ({
size='small'
label={t('Select Payment Currency')}
required={true}
value={currency}
value={fav.currency}
inputProps={{
style: { textAlign: 'center' },
}}
onChange={onCurrencyChange}
onChange={handleCurrencyChange}
>
<MenuItem value={0}>
<div style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap' }}>
@ -139,11 +188,12 @@ const BookControl = ({
))}
</Select>
</Grid>
) : null}
{width > verboseToolbarWidth ? (
<Grid item sx={{ position: 'relative', top: '0.5em' }}>
<Typography variant='caption' color='text.secondary'>
{currency == 1000 ? t('swap to') : t('pay with')}
{fav.currency == 1000 ? t(fav.type === 0 ? 'to' : 'from') : t('pay with')}
</Typography>
</Grid>
) : null}
@ -164,10 +214,10 @@ const BookControl = ({
listBoxProps={{ sx: { width: '13em' } }}
onAutocompleteChange={setPaymentMethods}
value={paymentMethod}
optionsType={currency == 1000 ? 'swap' : 'fiat'}
optionsType={fav.currency == 1000 ? 'swap' : 'fiat'}
error={false}
helperText={''}
label={currency == 1000 ? t('DESTINATION') : t('METHOD')}
label={fav.currency == 1000 ? t('DESTINATION') : t('METHOD')}
tooltipTitle=''
listHeaderText=''
addNewButtonText=''
@ -216,7 +266,7 @@ const BookControl = ({
</Typography>
</div>
</MenuItem>
{currency === 1000
{fav.currency === 1000
? swapMethods.map((method, index) => (
<MenuItem
style={{ width: '10em' }}

View File

@ -43,8 +43,7 @@ interface BookTableProps {
showControls?: boolean;
showFooter?: boolean;
showNoResults?: boolean;
onCurrencyChange?: (e: any) => void;
onTypeChange?: (mouseEvent: any, val: number) => void;
setFav?: (state: Favorites) => void;
onOrderClicked?: (id: number) => void;
baseUrl: string;
}
@ -52,7 +51,8 @@ interface BookTableProps {
const BookTable = ({
clickRefresh,
book,
fav = { currency: 1, type: 0 },
fav = { currency: 1, type: 0, mode: 'fiat' },
setFav,
maxWidth = 100,
maxHeight = 70,
fullWidth = 100,
@ -63,8 +63,6 @@ const BookTable = ({
showControls = true,
showFooter = true,
showNoResults = true,
onCurrencyChange,
onTypeChange,
onOrderClicked = () => null,
baseUrl,
}: BookTableProps): JSX.Element => {
@ -218,7 +216,10 @@ const BookTable = ({
field: 'type',
headerName: t('Is'),
width: width * fontSize,
renderCell: (params: any) => (params.row.type ? t('Seller') : t('Buyer')),
renderCell: (params: any) =>
params.row.type
? t(fav.mode === 'fiat' ? 'Seller' : 'Swapping Out')
: t(fav.mode === 'fiat' ? 'Buyer' : 'Swapping In'),
};
};
@ -230,14 +231,15 @@ const BookTable = ({
type: 'number',
width: width * fontSize,
renderCell: (params: any) => {
const amount = fav.mode === 'swap' ? params.row.amount * 100000 : params.row.amount;
const minAmount =
fav.mode === 'swap' ? params.row.min_amount * 100000 : params.row.min_amount;
const maxAmount =
fav.mode === 'swap' ? params.row.max_amount * 100000 : params.row.max_amount;
return (
<div style={{ cursor: 'pointer' }}>
{amountToString(
params.row.amount,
params.row.has_range,
params.row.min_amount,
params.row.max_amount,
)}
{amountToString(amount, params.row.has_range, minAmount, maxAmount) +
(fav.mode === 'swap' ? 'K Sats' : '')}
</div>
);
},
@ -246,7 +248,7 @@ const BookTable = ({
const currencyObj = function (width: number, hide: boolean) {
return {
hide,
hide: fav.mode === 'swap' ? true : hide,
field: 'currency',
headerName: t('Currency'),
width: width * fontSize,
@ -274,7 +276,7 @@ const BookTable = ({
return {
hide,
field: 'payment_method',
headerName: t('Payment Method'),
headerName: fav.mode === 'fiat' ? t('Payment Method') : t('Destination'),
width: width * fontSize,
renderCell: (params: any) => {
return (
@ -497,7 +499,7 @@ const BookTable = ({
priority: 1,
order: 4,
normal: {
width: 6.5,
width: fav.mode === 'swap' ? 9.5 : 6.5,
object: amountObj,
},
},
@ -505,7 +507,7 @@ const BookTable = ({
priority: 2,
order: 5,
normal: {
width: 5.9,
width: fav.mode === 'swap' ? 0 : 5.9,
object: currencyObj,
},
},
@ -577,7 +579,7 @@ const BookTable = ({
priority: 10,
order: 2,
normal: {
width: 4.3,
width: fav.mode === 'swap' ? 7 : 4.3,
object: typeObj,
},
},
@ -742,10 +744,8 @@ const BookTable = ({
componentsProps={{
toolbar: {
width,
type: fav.type,
currency: fav.currency,
onCurrencyChange,
onTypeChange,
fav,
setFav,
paymentMethod: paymentMethods,
setPaymentMethods,
},

View File

@ -148,7 +148,7 @@ function AmountRange({
<Grid
item
sx={{
width: `calc(100% - ${Math.log10(amountLimits[1] * 0.65) + 2}em)`,
width: `calc(100% - ${Math.abs(Math.log10(amountLimits[1]) * 0.65) + 2}em)`,
}}
>
<RangeSlider

View File

@ -8,6 +8,7 @@ import {
Switch,
Tooltip,
Button,
Checkbox,
Grid,
Typography,
TextField,
@ -36,7 +37,7 @@ import { FlagWithProps } from '../Icons';
import AutocompletePayments from './AutocompletePayments';
import AmountRange from './AmountRange';
import currencyDict from '../../../static/assets/currencies.json';
import { pn } from '../../utils';
import { amountToString, pn } from '../../utils';
import { SelfImprovement, Lock, HourglassTop, DeleteSweep, Edit } from '@mui/icons-material';
import { LoadingButton } from '@mui/lab';
@ -146,6 +147,7 @@ const MakerForm = ({
setFav({
...fav,
currency: newCurrency,
mode: newCurrency === 1000 ? 'swap' : 'fiat',
});
updateAmountLimits(limits.list, newCurrency, maker.premium);
updateCurrentPrice(limits.list, newCurrency, maker.premium);
@ -409,18 +411,23 @@ const MakerForm = ({
color={disableSubmit() ? 'text.secondary' : 'text.primary'}
>
{fav.type == null
? t('Order for ')
? t(fav.mode === 'fiat' ? 'Order for ' : 'Swap of ')
: fav.type == 1
? t('Buy order for ')
: t('Sell order for ')}
{maker.advancedOptions && maker.minAmount != ''
? pn(maker.minAmount) + '-' + pn(maker.maxAmount)
: pn(maker.amount)}
{' ' + currencyCode}
? t(fav.mode === 'fiat' ? 'Buy BTC for ' : 'Swap into LN ')
: t(fav.mode === 'fiat' ? 'Sell BTC for ' : 'Swap out of LN ')}
{fav.mode === 'fiat'
? amountToString(maker.amount, maker.advancedOptions, maker.minAmount, maker.maxAmount)
: amountToString(
maker.amount * 100000000,
maker.advancedOptions,
maker.minAmount * 100000000,
maker.maxAmount * 100000000,
)}
{' ' + (fav.mode === 'fiat' ? currencyCode : 'Sats')}
{maker.isExplicit
? t(' of {{satoshis}} Satoshis', { satoshis: pn(maker.satoshis) })
: maker.premium == 0
? t(' at market price')
? t(fav.mode === 'fiat' ? ' at market price' : '')
: maker.premium > 0
? t(' at a {{premium}}% premium', { premium: maker.premium })
: t(' at a {{discount}}% discount', { discount: -maker.premium })}
@ -491,10 +498,25 @@ const MakerForm = ({
<Collapse in={!collapseAll}>
<Grid container spacing={1} justifyContent='center' alignItems='center'>
<Grid item>
<Grid container direction='row' justifyContent='center' alignItems='stretch'>
<Collapse in={maker.advancedOptions} orientation='horizontal'>
<Grid item>
<FormControl>
<FormHelperText sx={{ textAlign: 'center' }}>{t('Swap?')}</FormHelperText>
<Checkbox
sx={{ position: 'relative', bottom: '0.3em' }}
checked={fav.mode == 'swap'}
onClick={() => handleCurrencyChange(fav.mode == 'swap' ? 1 : 1000)}
/>
</FormControl>
</Grid>
</Collapse>
<Grid item>
<FormControl component='fieldset'>
<FormHelperText sx={{ textAlign: 'center' }}>
{t('Buy or Sell Bitcoin?')}
{fav.mode === 'fiat' ? t('Buy or Sell Bitcoin?') : t('In or Out of Lightning?')}
</FormHelperText>
<div style={{ textAlign: 'center' }}>
<ButtonGroup>
@ -516,7 +538,7 @@ const MakerForm = ({
},
}}
>
{t('Buy')}
{fav.mode === 'fiat' ? t('Buy') : t('Swap In')}
</Button>
<Button
size={maker.advancedOptions ? 'small' : 'large'}
@ -537,12 +559,14 @@ const MakerForm = ({
},
}}
>
{t('Sell')}
{fav.mode === 'fiat' ? t('Sell') : t('Swap Out')}
</Button>
</ButtonGroup>
</div>
</FormControl>
</Grid>
</Grid>
</Grid>
<Grid item>
<Collapse in={maker.advancedOptions}>
@ -637,10 +661,10 @@ const MakerForm = ({
<AutocompletePayments
onAutocompleteChange={handlePaymentMethodChange}
// listBoxProps={{ sx: { width: '15.3em', maxHeight: '20em' } }}
optionsType={fav.currency == 1000 ? 'swap' : 'fiat'}
optionsType={fav.mode}
error={maker.badPaymentMethod}
helperText={maker.badPaymentMethod ? t('Must be shorter than 65 characters') : ''}
label={fav.currency == 1000 ? t('Swap Destination(s)') : t('Fiat Payment Method(s)')}
label={fav.mode == 'swap' ? t('Swap Destination(s)') : t('Fiat Payment Method(s)')}
tooltipTitle={t(
'Enter your preferred fiat payment methods. Fast methods are highly recommended.',
)}

View File

@ -54,7 +54,7 @@ const TakeButton = ({
const [loadingTake, setLoadingTake] = useState<boolean>(false);
const [open, setOpen] = useState<OpenDialogsProps>(closeAll);
const currencyCode: string = currencies[`${order.currency}`];
const currencyCode: string = order.currency == 1000 ? 'Sats' : currencies[`${order.currency}`];
const InactiveMakerDialog = function () {
return (
@ -104,9 +104,10 @@ const TakeButton = ({
};
const amountHelperText = function () {
if (Number(takeAmount) < Number(order.min_amount) && takeAmount != '') {
const amount = order.currency == 1000 ? Number(takeAmount) / 100000000 : Number(takeAmount);
if (amount < Number(order.min_amount) && takeAmount != '') {
return t('Too low');
} else if (Number(takeAmount) > Number(order.max_amount) && takeAmount != '') {
} else if (amount > Number(order.max_amount) && takeAmount != '') {
return t('Too high');
} else {
return null;
@ -122,9 +123,10 @@ const TakeButton = ({
};
const invalidTakeAmount = function () {
const amount = order.currency == 1000 ? Number(takeAmount) / 100000000 : Number(takeAmount);
return (
Number(takeAmount) < Number(order.min_amount) ||
Number(takeAmount) > Number(order.max_amount) ||
amount < Number(order.min_amount) ||
amount > Number(order.max_amount) ||
takeAmount == '' ||
takeAmount == null
);
@ -146,7 +148,7 @@ const TakeButton = ({
}}
>
<Grid container direction='row' alignItems='flex-start' justifyContent='space-evenly'>
<Grid item>
<Grid item sx={{ width: '12em' }}>
<Tooltip
placement='top'
enterTouchDelay={500}
@ -155,11 +157,7 @@ const TakeButton = ({
title={t('Enter amount of fiat to exchange for bitcoin')}
>
<TextField
error={
(Number(takeAmount) < Number(order.min_amount) ||
Number(takeAmount) > Number(order.max_amount)) &&
takeAmount != ''
}
error={takeAmount === '' ? false : invalidTakeAmount()}
helperText={amountHelperText()}
label={t('Amount {{currencyCode}}', { currencyCode })}
size='small'
@ -249,7 +247,7 @@ const TakeButton = ({
apiClient
.post(baseUrl, '/api/order/?order_id=' + order.id, {
action: 'take',
amount: takeAmount,
amount: order.currency == 1000 ? takeAmount / 100000000 : takeAmount,
})
.then((data) => {
setLoadingTake(false);

View File

@ -32,7 +32,7 @@ import { FlagWithProps } from '../Icons';
import LinearDeterminate from './LinearDeterminate';
import { Order } from '../../models';
import { statusBadgeColor, pn } from '../../utils';
import { statusBadgeColor, pn, amountToString } from '../../utils';
import { Page } from '../../basic/NavBar';
import TakeButton from './TakeButton';
@ -58,21 +58,23 @@ const OrderDetails = ({
const AmountString = function () {
// precision to 8 decimal if currency is BTC otherwise 4 decimals
const precision = order.currency == 1000 ? 8 : 4;
let primary = '';
let secondary = '';
if (order.has_range && order.amount == null) {
const minAmount = pn(parseFloat(Number(order.min_amount).toPrecision(precision)));
const maxAmount = pn(parseFloat(Number(order.max_amount).toPrecision(precision)));
primary = `${minAmount}-${maxAmount} ${currencyCode}`;
secondary = t('Amount range');
if (order.currency == 1000) {
return (
amountToString(
order.amount * 100000000,
order.amount ? false : order.has_range,
order.min_amount * 100000000,
order.max_amount * 100000000,
) + ' Sats'
);
} else {
const amount = pn(parseFloat(Number(order.amount).toPrecision(precision)));
primary = `${amount} ${currencyCode}`;
secondary = t('Amount');
return amountToString(
order.amount,
order.amount ? false : order.has_range,
order.min_amount,
order.max_amount,
);
}
return { primary, secondary };
};
// Countdown Renderer callback with condition
@ -151,7 +153,11 @@ const OrderDetails = ({
/>
</ListItemAvatar>
<ListItemText
primary={order.maker_nick + (order.type ? ' ' + t('(Seller)') : ' ' + t('(Buyer)'))}
primary={`${order.maker_nick} (${
order.type
? t(order.currency == 1000 ? 'Swapping Out' : 'Seller')
: t(order.currency == 1000 ? 'Swapping In' : 'Buyer')
})`}
secondary={t('Order maker')}
/>
</ListItem>
@ -160,7 +166,11 @@ const OrderDetails = ({
<Divider />
<ListItem>
<ListItemText
primary={`${order.taker_nick} ${order.type ? t('(Buyer)') : t('(Seller)')}`}
primary={`${order.taker_nick} (${
order.type
? t(order.currency == 1000 ? 'Swapping In' : 'Buyer')
: t(order.currency == 1000 ? 'Swapping Out' : 'Seller')
})`}
secondary={t('Order taker')}
/>
<ListItemAvatar>
@ -205,7 +215,10 @@ const OrderDetails = ({
<FlagWithProps code={currencyCode} width='1.2em' height='1.2em' />
</div>
</ListItemIcon>
<ListItemText primary={AmountString().primary} secondary={AmountString().secondary} />
<ListItemText
primary={AmountString()}
secondary={order.amount && !order.has_range ? 'Amount' : 'Amount Range'}
/>
</ListItem>
<Divider />

View File

@ -14,7 +14,7 @@ import {
ToggleButtonGroup,
ToggleButton,
} from '@mui/material';
import { Settings } from '../../models';
import { Favorites, Settings } from '../../models';
import SelectLanguage from './SelectLanguage';
import {
Translate,
@ -23,11 +23,16 @@ import {
DarkMode,
SettingsOverscan,
Link,
AccountBalance,
AttachMoney,
} from '@mui/icons-material';
import { systemClient } from '../../services/System';
import SwapCalls from '@mui/icons-material/SwapCalls';
interface SettingsFormProps {
dense?: boolean;
fav: Favorites;
setFav: (state: Favorites) => void;
settings: Settings;
setSettings: (state: Settings) => void;
showNetwork?: boolean;
@ -35,6 +40,8 @@ interface SettingsFormProps {
const SettingsForm = ({
dense = false,
fav,
setFav,
settings,
setSettings,
showNetwork = false,
@ -139,6 +146,29 @@ const SettingsForm = ({
track={false}
/>
</ListItem>
<ListItem>
<ListItemIcon>
<AccountBalance />
</ListItemIcon>
<ToggleButtonGroup
exclusive={true}
value={fav.mode}
onChange={(e, mode) => {
setFav({ ...fav, mode, currency: mode === 'fiat' ? 0 : 1000 });
}}
>
<ToggleButton value='fiat' color='primary'>
<AttachMoney />
{t('Fiat')}
</ToggleButton>
<ToggleButton value='swap' color='secondary'>
<SwapCalls />
{t('Swaps')}
</ToggleButton>
</ToggleButtonGroup>
</ListItem>
{showNetwork ? (
<ListItem>
<ListItemIcon>

View File

@ -56,18 +56,22 @@ export const LockInvoicePrompt = ({ order, concept }: LockInvoicePromptProps): J
alignItems='center'
spacing={0.5}
>
<Grid item xs={12}>
{concept === 'bond' ? <WalletsButton /> : <ExpirationWarning />}
</Grid>
{concept == 'bond' ? (
<Typography color='secondary'>
<b>{t(`You are ${order.is_buyer ? 'BUYING' : 'SELLING'} BTC`)}</b>
<Typography color='secondary' variant='h6' align='center'>
<b>
{order.currency == 1000
? t(`${order.is_buyer ? 'SWAPPING INTO' : 'SWAPPING OUT of'} Lightning`)
: t(`You are ${order.is_buyer ? 'BUYING' : 'SELLING'} BTC`)}
</b>
</Typography>
) : (
<></>
)}
<Grid item xs={12}>
{concept === 'bond' ? <WalletsButton /> : <ExpirationWarning />}
</Grid>
<Grid item xs={12}>
<Tooltip disableHoverListener enterTouchDelay={0} title={t('Copied!')}>
<Box

View File

@ -54,9 +54,13 @@ export const PayoutPrompt = ({
'Before letting you send {{amountFiat}} {{currencyCode}}, we want to make sure you are able to receive the BTC.',
{
amountFiat: pn(
parseFloat(parseFloat(order.amount).toFixed(order.currency == 1000 ? 8 : 4)),
parseFloat(
parseFloat(
order.currency == 1000 ? order.amount * 100000000 : order.amount,
).toFixed(4),
),
currencyCode,
),
currencyCode: order.currency == 1000 ? 'Sats' : currencyCode,
},
)}
</Typography>

View File

@ -1,5 +1,6 @@
export interface Favorites {
type: number | null;
mode: 'swap' | 'fiat';
currency: number;
}

View File

@ -50,11 +50,12 @@ const filterOrders = function ({
}: FilterOrders) {
const filteredOrders = orders.filter((order) => {
const typeChecks = order.type == baseFilter.type || baseFilter.type == null;
const modeChecks = baseFilter.mode === 'fiat' ? !(order.currency === 1000) : true;
const currencyChecks = order.currency == baseFilter.currency || baseFilter.currency == 0;
const paymentMethodChecks =
paymentMethods.length > 0 ? filterByPayment(order, paymentMethods) : true;
const amountChecks = amountFilter != null ? filterByAmount(order, amountFilter) : true;
return typeChecks && currencyChecks && paymentMethodChecks && amountChecks;
return typeChecks && modeChecks && currencyChecks && paymentMethodChecks && amountChecks;
});
return filteredOrders;
};

View File

@ -15,15 +15,16 @@ export const amountToString: (
has_range: boolean,
min_amount: number,
max_amount: number,
) => string = (amount, has_range, min_amount, max_amount) => {
precision?: number,
) => string = (amount, has_range, min_amount, max_amount, precision = 4) => {
if (has_range) {
return (
pn(parseFloat(Number(min_amount).toPrecision(4))) +
pn(parseFloat(Number(min_amount).toPrecision(precision))) +
'-' +
pn(parseFloat(Number(max_amount).toPrecision(4)))
pn(parseFloat(Number(max_amount).toPrecision(precision)))
);
}
return pn(parseFloat(Number(amount).toPrecision(4))) || '';
return pn(parseFloat(Number(amount).toPrecision(precision))) || '';
};
export default pn;