mirror of
https://github.com/RoboSats/robosats.git
synced 2024-12-13 19:06:26 +00:00
Merge pull request #1563 from RoboSats/generate-robot-and-alert
Generate Robot and Order
This commit is contained in:
commit
1eac225853
@ -1,27 +1,20 @@
|
||||
import React, { useContext, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button, Grid, ButtonGroup, Dialog, Box } from '@mui/material';
|
||||
import { Button, Grid, ButtonGroup } from '@mui/material';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import DepthChart from '../../components/Charts/DepthChart';
|
||||
|
||||
import { NoRobotDialog } from '../../components/Dialogs';
|
||||
import MakerForm from '../../components/MakerForm';
|
||||
import BookTable from '../../components/BookTable';
|
||||
|
||||
// Icons
|
||||
import { BarChart, FormatListBulleted, Map } from '@mui/icons-material';
|
||||
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
|
||||
import MapChart from '../../components/Charts/MapChart';
|
||||
import { GarageContext, type UseGarageStoreType } from '../../contexts/GarageContext';
|
||||
|
||||
const BookPage = (): JSX.Element => {
|
||||
const { windowSize } = useContext<UseAppStoreType>(AppContext);
|
||||
const { garage } = useContext<UseGarageStoreType>(GarageContext);
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const [view, setView] = useState<'list' | 'depth' | 'map'>('list');
|
||||
const [openMaker, setOpenMaker] = useState<boolean>(false);
|
||||
const [openNoRobot, setOpenNoRobot] = useState<boolean>(false);
|
||||
|
||||
const doubleView = windowSize.width > 115;
|
||||
const width = windowSize.width * 0.9;
|
||||
@ -29,11 +22,7 @@ const BookPage = (): JSX.Element => {
|
||||
const chartWidthEm = width - maxBookTableWidth;
|
||||
|
||||
const onOrderClicked = function (id: number, shortAlias: string): void {
|
||||
if (garage.getSlot()?.hashId) {
|
||||
navigate(`/order/${shortAlias}/${id}`);
|
||||
} else {
|
||||
setOpenNoRobot(true);
|
||||
}
|
||||
navigate(`/order/${shortAlias}/${id}`);
|
||||
};
|
||||
|
||||
const NavButtons = function (): JSX.Element {
|
||||
@ -42,7 +31,7 @@ const BookPage = (): JSX.Element => {
|
||||
<Button
|
||||
color='primary'
|
||||
onClick={() => {
|
||||
setOpenMaker(true);
|
||||
navigate('/create');
|
||||
}}
|
||||
>
|
||||
{t('Create')}
|
||||
@ -80,32 +69,6 @@ const BookPage = (): JSX.Element => {
|
||||
|
||||
return (
|
||||
<Grid container direction='column' alignItems='center' spacing={1} sx={{ minWidth: 400 }}>
|
||||
<NoRobotDialog
|
||||
open={openNoRobot}
|
||||
onClose={() => {
|
||||
setOpenNoRobot(false);
|
||||
}}
|
||||
onClickGenerateRobot={() => {
|
||||
navigate('/garage');
|
||||
}}
|
||||
/>
|
||||
{openMaker ? (
|
||||
<Dialog
|
||||
open={openMaker}
|
||||
onClose={() => {
|
||||
setOpenMaker(false);
|
||||
}}
|
||||
>
|
||||
<Box sx={{ maxWidth: '18em', padding: '0.5em' }}>
|
||||
<MakerForm
|
||||
onClickGenerateRobot={() => {
|
||||
navigate('/garage');
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Dialog>
|
||||
) : null}
|
||||
|
||||
<Grid item xs={12}>
|
||||
{doubleView ? (
|
||||
<Grid
|
||||
|
@ -2,7 +2,7 @@ import React, { useContext, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Grid, Paper, Collapse, Typography } from '@mui/material';
|
||||
import { filterOrders } from '../../utils';
|
||||
import { filterOrders, genBase62Token } from '../../utils';
|
||||
|
||||
import MakerForm from '../../components/MakerForm';
|
||||
import BookTable from '../../components/BookTable';
|
||||
@ -22,6 +22,7 @@ const MakerPage = (): JSX.Element => {
|
||||
const maxHeight = (windowSize.height - navbarHeight) * 0.85 - 3;
|
||||
const [showMatches, setShowMatches] = useState<boolean>(false);
|
||||
const [openNoRobot, setOpenNoRobot] = useState<boolean>(false);
|
||||
const [clickedOrder, setClickedOrder] = useState<{ id: number; shortAlias: string }>();
|
||||
|
||||
const matches = useMemo(() => {
|
||||
return filterOrders({
|
||||
@ -55,6 +56,7 @@ const MakerPage = (): JSX.Element => {
|
||||
if (garage.getSlot()?.hashId) {
|
||||
navigate(`/order/${shortAlias}/${id}`);
|
||||
} else {
|
||||
setClickedOrder({ id, shortAlias });
|
||||
setOpenNoRobot(true);
|
||||
}
|
||||
};
|
||||
@ -67,7 +69,16 @@ const MakerPage = (): JSX.Element => {
|
||||
setOpenNoRobot(false);
|
||||
}}
|
||||
onClickGenerateRobot={() => {
|
||||
navigate('/garage');
|
||||
const token = genBase62Token(36);
|
||||
garage
|
||||
.createRobot(federation, token)
|
||||
.then(() => {
|
||||
setOpenNoRobot(true);
|
||||
if (clickedOrder) navigate(`/order/${clickedOrder?.shortAlias}/${clickedOrder?.id}`);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Grid item>
|
||||
@ -111,9 +122,6 @@ const MakerPage = (): JSX.Element => {
|
||||
setShowMatches(false);
|
||||
}}
|
||||
submitButtonLabel={matches.length > 0 && !showMatches ? 'Submit' : 'Create order'}
|
||||
onClickGenerateRobot={() => {
|
||||
navigate('/garage');
|
||||
}}
|
||||
/>
|
||||
</Paper>
|
||||
</Grid>
|
||||
|
@ -8,9 +8,10 @@ import OrderDetails from '../../components/OrderDetails';
|
||||
|
||||
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
|
||||
import { FederationContext, type UseFederationStoreType } from '../../contexts/FederationContext';
|
||||
import { WarningDialog } from '../../components/Dialogs';
|
||||
import { NoRobotDialog, WarningDialog } from '../../components/Dialogs';
|
||||
import { Order, type Slot } from '../../models';
|
||||
import { type UseGarageStoreType, GarageContext } from '../../contexts/GarageContext';
|
||||
import { genBase62Token } from '../../utils';
|
||||
|
||||
const OrderPage = (): JSX.Element => {
|
||||
const { windowSize, setOpen, acknowledgedWarning, setAcknowledgedWarning, navbarHeight } =
|
||||
@ -27,6 +28,7 @@ const OrderPage = (): JSX.Element => {
|
||||
|
||||
const [tab, setTab] = useState<'order' | 'contract'>('contract');
|
||||
const [currentOrder, setCurrentOrder] = useState<Order | null>(null);
|
||||
const [openNoRobot, setOpenNoRobot] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
paramsRef.current = params;
|
||||
@ -43,12 +45,14 @@ const OrderPage = (): JSX.Element => {
|
||||
void order.fecth(federation, slot).then((updatedOrder) => {
|
||||
updateSlotFromOrder(updatedOrder, slot);
|
||||
});
|
||||
} else {
|
||||
setOpenNoRobot(true);
|
||||
}
|
||||
|
||||
return () => {
|
||||
setCurrentOrder(null);
|
||||
};
|
||||
}, [params.orderId]);
|
||||
}, [params.orderId, openNoRobot]);
|
||||
|
||||
const updateSlotFromOrder = (updatedOrder: Order, slot: Slot): void => {
|
||||
if (
|
||||
@ -77,9 +81,6 @@ const OrderPage = (): JSX.Element => {
|
||||
shortAlias={String(currentOrder.shortAlias)}
|
||||
currentOrder={currentOrder}
|
||||
onClickCoordinator={onClickCoordinator}
|
||||
onClickGenerateRobot={() => {
|
||||
navigate('/garage');
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
@ -100,6 +101,23 @@ const OrderPage = (): JSX.Element => {
|
||||
}}
|
||||
longAlias={federation.getCoordinator(params.shortAlias ?? '')?.longAlias}
|
||||
/>
|
||||
<NoRobotDialog
|
||||
open={openNoRobot}
|
||||
onClose={() => {
|
||||
setOpenNoRobot(false);
|
||||
}}
|
||||
onClickGenerateRobot={() => {
|
||||
const token = genBase62Token(36);
|
||||
garage
|
||||
.createRobot(federation, token)
|
||||
.then(() => {
|
||||
setOpenNoRobot(false);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
});
|
||||
}}
|
||||
/>
|
||||
{!currentOrder?.maker_hash_id && <CircularProgress />}
|
||||
{currentOrder?.bad_request && currentOrder.status !== 5 ? (
|
||||
<Typography align='center' variant='subtitle2' color='secondary'>
|
||||
|
@ -116,7 +116,7 @@ const Onboarding = ({ setView, inputToken, setInputToken }: OnboardingProps): JS
|
||||
<Button
|
||||
onClick={() => {
|
||||
setStep('2');
|
||||
garage.createRobot(federation, inputToken);
|
||||
void garage.createRobot(federation, inputToken);
|
||||
}}
|
||||
variant='contained'
|
||||
size='large'
|
||||
|
@ -58,7 +58,7 @@ const RobotProfile = ({
|
||||
|
||||
const handleAddRobot = (): void => {
|
||||
const token = genBase62Token(36);
|
||||
garage.createRobot(federation, token);
|
||||
void garage.createRobot(federation, token);
|
||||
setInputToken(token);
|
||||
setLoading(true);
|
||||
};
|
||||
|
@ -121,7 +121,7 @@ const Welcome = ({ setView, width, setInputToken }: WelcomeProps): JSX.Element =
|
||||
color='primary'
|
||||
onClick={() => {
|
||||
const token = genBase62Token(36);
|
||||
garage.createRobot(federation, token);
|
||||
void garage.createRobot(federation, token);
|
||||
setInputToken(token);
|
||||
navigate('/create');
|
||||
setPage('create');
|
||||
|
@ -25,7 +25,7 @@ const RecoveryDialog = ({ setInputToken, setView }: Props): JSX.Element => {
|
||||
}, [open.recovery]);
|
||||
|
||||
const onClickRecover = (): void => {
|
||||
garage.createRobot(federation, recoveryToken);
|
||||
void garage.createRobot(federation, recoveryToken);
|
||||
setInputToken(recoveryToken.trim());
|
||||
setView('profile');
|
||||
setOpen((open) => {
|
||||
|
@ -34,7 +34,7 @@ import { FlagWithProps } from '../Icons';
|
||||
import AutocompletePayments from './AutocompletePayments';
|
||||
import AmountRange from './AmountRange';
|
||||
import currencyDict from '../../../static/assets/currencies.json';
|
||||
import { amountToString, computeSats, pn } from '../../utils';
|
||||
import { amountToString, computeSats, genBase62Token, pn } from '../../utils';
|
||||
|
||||
import { SelfImprovement, Lock, HourglassTop, DeleteSweep, Edit, Map } from '@mui/icons-material';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
@ -52,7 +52,6 @@ interface MakerFormProps {
|
||||
onSubmit?: () => void;
|
||||
onReset?: () => void;
|
||||
submitButtonLabel?: string;
|
||||
onClickGenerateRobot?: () => void;
|
||||
}
|
||||
|
||||
const MakerForm = ({
|
||||
@ -62,7 +61,6 @@ const MakerForm = ({
|
||||
onSubmit = () => {},
|
||||
onReset = () => {},
|
||||
submitButtonLabel = 'Create Order',
|
||||
onClickGenerateRobot = () => null,
|
||||
}: MakerFormProps): JSX.Element => {
|
||||
const { fav, setFav } = useContext<UseAppStoreType>(AppContext);
|
||||
const { federation, federationUpdatedAt } = useContext<UseFederationStoreType>(FederationContext);
|
||||
@ -582,7 +580,18 @@ const MakerForm = ({
|
||||
}}
|
||||
onClickDone={handleCreateOrder}
|
||||
hasRobot={Boolean(garage.getSlot()?.hashId)}
|
||||
onClickGenerateRobot={onClickGenerateRobot}
|
||||
onClickGenerateRobot={() => {
|
||||
setOpenDialogs(false);
|
||||
const token = genBase62Token(36);
|
||||
garage
|
||||
.createRobot(federation, token)
|
||||
.then(() => {
|
||||
setOpenDialogs(true);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<F2fMapDialog
|
||||
interactive
|
||||
|
@ -2,8 +2,6 @@ import React, { createContext, useEffect, useState, useContext, type ReactNode }
|
||||
|
||||
import { Federation, Settings } from '../models';
|
||||
|
||||
import { federationLottery } from '../utils';
|
||||
|
||||
import { AppContext, type UseAppStoreType } from './AppContext';
|
||||
import { GarageContext, type UseGarageStoreType } from './GarageContext';
|
||||
import type Coordinator from '../models/Coordinator.model';
|
||||
|
@ -129,33 +129,35 @@ class Garage {
|
||||
};
|
||||
|
||||
// Robots
|
||||
createRobot: (federation: Federation, token: string) => void = (federation, token) => {
|
||||
createRobot: (federation: Federation, token: string) => Promise<void> = async (
|
||||
federation,
|
||||
token,
|
||||
) => {
|
||||
if (!token) return;
|
||||
|
||||
if (this.getSlot(token) === null) {
|
||||
genKey(token)
|
||||
.then((key) => {
|
||||
const robotAttributes = {
|
||||
token,
|
||||
pubKey: key.publicKeyArmored,
|
||||
encPrivKey: key.encryptedPrivateKeyArmored,
|
||||
};
|
||||
try {
|
||||
const key = await genKey(token);
|
||||
const robotAttributes = {
|
||||
token,
|
||||
pubKey: key.publicKeyArmored,
|
||||
encPrivKey: key.encryptedPrivateKeyArmored,
|
||||
};
|
||||
|
||||
this.setCurrentSlot(token);
|
||||
this.slots[token] = new Slot(
|
||||
token,
|
||||
Object.keys(federation.coordinators),
|
||||
robotAttributes,
|
||||
() => {
|
||||
this.triggerHook('onSlotUpdate');
|
||||
},
|
||||
);
|
||||
void this.fetchRobot(federation, token);
|
||||
this.save();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error:', error);
|
||||
});
|
||||
this.setCurrentSlot(token);
|
||||
this.slots[token] = new Slot(
|
||||
token,
|
||||
Object.keys(federation.coordinators),
|
||||
robotAttributes,
|
||||
() => {
|
||||
this.triggerHook('onSlotUpdate');
|
||||
},
|
||||
);
|
||||
void this.fetchRobot(federation, token);
|
||||
this.save();
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user