mirror of
https://github.com/RoboSats/robosats.git
synced 2025-01-18 12:11:35 +00:00
Refactor info endpoint calls
This commit is contained in:
parent
560def2966
commit
7bf77a538e
@ -1,4 +1,4 @@
|
||||
import React, { useContext, useMemo, useState } from 'react';
|
||||
import React, { useContext, useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Grid, Paper, Collapse, Typography } from '@mui/material';
|
||||
@ -13,7 +13,7 @@ import { FederationContext, type UseFederationStoreType } from '../../contexts/F
|
||||
import { GarageContext, type UseGarageStoreType } from '../../contexts/GarageContext';
|
||||
|
||||
const MakerPage = (): JSX.Element => {
|
||||
const { fav, windowSize, navbarHeight } = useContext<UseAppStoreType>(AppContext);
|
||||
const { fav, windowSize, navbarHeight, page } = useContext<UseAppStoreType>(AppContext);
|
||||
const { federation } = useContext<UseFederationStoreType>(FederationContext);
|
||||
const { garage, maker } = useContext<UseGarageStoreType>(GarageContext);
|
||||
const { t } = useTranslation();
|
||||
|
@ -22,6 +22,7 @@ import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
|
||||
import { genBase62Token } from '../../utils';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
import { GarageContext, type UseGarageStoreType } from '../../contexts/GarageContext';
|
||||
import { FederationContext, UseFederationStoreType } from '../../contexts/FederationContext';
|
||||
|
||||
interface RobotProfileProps {
|
||||
robot: Robot;
|
||||
@ -45,6 +46,7 @@ const RobotProfile = ({
|
||||
}: RobotProfileProps): JSX.Element => {
|
||||
const { windowSize, client } = useContext<UseAppStoreType>(AppContext);
|
||||
const { garage, slotUpdatedAt } = useContext<UseGarageStoreType>(GarageContext);
|
||||
const { federation } = useContext<UseFederationStoreType>(FederationContext);
|
||||
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
@ -75,10 +77,6 @@ const RobotProfile = ({
|
||||
const slot = garage.getSlot();
|
||||
const robot = slot?.getRobot();
|
||||
|
||||
const loadingCoordinators = Object.values(slot?.robots ?? {}).filter(
|
||||
(robot) => robot.loading,
|
||||
).length;
|
||||
|
||||
return (
|
||||
<Grid container direction='column' alignItems='center' spacing={1} padding={1} paddingTop={2}>
|
||||
<Grid
|
||||
@ -154,7 +152,7 @@ const RobotProfile = ({
|
||||
)}
|
||||
</Grid>
|
||||
|
||||
{loadingCoordinators > 0 && !slot?.activeOrder?.id ? (
|
||||
{federation.loading && !slot?.activeOrder?.id ? (
|
||||
<Grid>
|
||||
<b>{t('Looking for orders!')}</b>
|
||||
<LinearProgress />
|
||||
@ -208,7 +206,7 @@ const RobotProfile = ({
|
||||
</Grid>
|
||||
) : null}
|
||||
|
||||
{!slot?.activeOrder && !slot?.lastOrder && loadingCoordinators === 0 ? (
|
||||
{!slot?.activeOrder && !slot?.lastOrder && !federation.loading ? (
|
||||
<Grid item>{t('No existing orders found')}</Grid>
|
||||
) : null}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useContext, useState } from 'react';
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import { Box, Button, Grid, List, ListItem, Paper, TextField, Typography } from '@mui/material';
|
||||
import SettingsForm from '../../components/SettingsForm';
|
||||
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
|
||||
@ -8,7 +8,7 @@ import { FederationContext, type UseFederationStoreType } from '../../contexts/F
|
||||
import { GarageContext, type UseGarageStoreType } from '../../contexts/GarageContext';
|
||||
|
||||
const SettingsPage = (): JSX.Element => {
|
||||
const { windowSize, navbarHeight } = useContext<UseAppStoreType>(AppContext);
|
||||
const { windowSize, navbarHeight, page } = useContext<UseAppStoreType>(AppContext);
|
||||
const { federation, addNewCoordinator } = useContext<UseFederationStoreType>(FederationContext);
|
||||
const { garage } = useContext<UseGarageStoreType>(GarageContext);
|
||||
const maxHeight = (windowSize.height - navbarHeight) * 0.85 - 3;
|
||||
@ -37,6 +37,10 @@ const SettingsPage = (): JSX.Element => {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (page === 'settings') void federation.loadInfo();
|
||||
}, [page]);
|
||||
|
||||
return (
|
||||
<Paper
|
||||
elevation={12}
|
||||
|
@ -827,7 +827,7 @@ const BookTable = ({
|
||||
<Grid item xs={6}>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
void federation.updateBook();
|
||||
void federation.loadBook();
|
||||
}}
|
||||
>
|
||||
<Refresh />
|
||||
@ -902,10 +902,6 @@ const BookTable = ({
|
||||
: orders;
|
||||
}, [showControls, orders, fav, paymentMethods]);
|
||||
|
||||
const loadingPercentage =
|
||||
((federation.exchange.enabledCoordinators - federation.exchange.loadingCoordinators) /
|
||||
federation.exchange.enabledCoordinators) *
|
||||
100;
|
||||
if (!fullscreen) {
|
||||
return (
|
||||
<Paper
|
||||
@ -938,11 +934,8 @@ const BookTable = ({
|
||||
setPaymentMethods,
|
||||
},
|
||||
loadingOverlay: {
|
||||
variant:
|
||||
federation.exchange.loadingCache || loadingPercentage === 0
|
||||
? 'indeterminate'
|
||||
: 'determinate',
|
||||
value: federation.exchange.loadingCache ? 1 : loadingPercentage,
|
||||
variant: 'indeterminate',
|
||||
value: federation.loading ? 0 : 100,
|
||||
},
|
||||
}}
|
||||
paginationModel={paginationModel}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useContext, useState } from 'react';
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import {
|
||||
@ -68,8 +68,9 @@ import {
|
||||
} from '../Icons';
|
||||
import { AppContext } from '../../contexts/AppContext';
|
||||
import { systemClient } from '../../services/System';
|
||||
import { type Badges } from '../../models/Coordinator.model';
|
||||
import Coordinator, { type Badges } from '../../models/Coordinator.model';
|
||||
import { type UseFederationStoreType, FederationContext } from '../../contexts/FederationContext';
|
||||
import { width } from '@mui/system';
|
||||
|
||||
interface Props {
|
||||
open: boolean;
|
||||
@ -348,18 +349,28 @@ const CoordinatorDialog = ({ open = false, onClose, shortAlias }: Props): JSX.El
|
||||
const { t } = useTranslation();
|
||||
const { clientVersion, page, settings, origin } = useContext(AppContext);
|
||||
const { federation } = useContext<UseFederationStoreType>(FederationContext);
|
||||
const coordinator = federation.getCoordinator(shortAlias ?? '');
|
||||
|
||||
const [expanded, setExpanded] = useState<'summary' | 'stats' | 'policies' | undefined>(undefined);
|
||||
const [coordinator, setCoordinator] = useState<Coordinator>(
|
||||
federation.getCoordinator(shortAlias ?? ''),
|
||||
);
|
||||
|
||||
const listItemProps = { sx: { maxHeight: '3em', width: '100%' } };
|
||||
const coordinatorVersion = `v${coordinator?.info?.version?.major ?? '?'}.${
|
||||
coordinator?.info?.version?.minor ?? '?'
|
||||
}.${coordinator?.info?.version?.patch ?? '?'}`;
|
||||
|
||||
useEffect(() => {
|
||||
setCoordinator(federation.getCoordinator(shortAlias ?? ''));
|
||||
}, [shortAlias]);
|
||||
|
||||
useEffect(() => {
|
||||
if (open) federation.getCoordinator(shortAlias ?? '')?.loadInfo();
|
||||
}, [open]);
|
||||
|
||||
return (
|
||||
<Dialog open={open} onClose={onClose}>
|
||||
<DialogContent>
|
||||
<DialogContent style={{ width: 600 }}>
|
||||
<Typography align='center' component='h5' variant='h5'>
|
||||
{String(coordinator?.longAlias)}
|
||||
</Typography>
|
||||
@ -483,7 +494,7 @@ const CoordinatorDialog = ({ open = false, onClose, shortAlias }: Props): JSX.El
|
||||
</ListItemButton>
|
||||
</List>
|
||||
|
||||
{coordinator?.loadingInfo ? (
|
||||
{!coordinator || coordinator?.loadingInfo ? (
|
||||
<Box style={{ display: 'flex', justifyContent: 'center' }}>
|
||||
<CircularProgress />
|
||||
</Box>
|
||||
|
@ -35,18 +35,11 @@ interface Props {
|
||||
const ExchangeDialog = ({ open = false, onClose }: Props): JSX.Element => {
|
||||
const { t } = useTranslation();
|
||||
const { federation, federationUpdatedAt } = useContext(FederationContext);
|
||||
const [loadingProgress, setLoadingProgress] = useState<number>(0);
|
||||
|
||||
useEffect(() => {
|
||||
const loadedCoordinators =
|
||||
federation.exchange.enabledCoordinators - federation.exchange.loadingCoordinators;
|
||||
setLoadingProgress((loadedCoordinators / federation.exchange.enabledCoordinators) * 100);
|
||||
}, [open, federationUpdatedAt]);
|
||||
|
||||
return (
|
||||
<Dialog open={open} onClose={onClose}>
|
||||
<div style={loadingProgress < 100 ? {} : { display: 'none' }}>
|
||||
<LinearProgress variant='determinate' value={loadingProgress} />
|
||||
<div style={federation.loading ? {} : { display: 'none' }}>
|
||||
<LinearProgress variant='indeterminate' />
|
||||
</div>
|
||||
<DialogContent>
|
||||
<Typography component='h5' variant='h5'>
|
||||
|
@ -33,15 +33,13 @@ const ProfileDialog = ({ open = false, onClose }: Props): JSX.Element => {
|
||||
const slot = garage.getSlot();
|
||||
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [loadingCoordinators, setLoadingCoordinators] = useState<number>(
|
||||
const [loadingRobots, setLoadingRobots] = useState<number>(
|
||||
Object.values(slot?.robots ?? {}).length,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setLoading(!garage.getSlot()?.hashId);
|
||||
setLoadingCoordinators(
|
||||
Object.values(slot?.robots ?? {}).filter((robot) => robot.loading).length,
|
||||
);
|
||||
setLoadingRobots(Object.values(slot?.robots ?? {}).filter((robot) => robot.loading).length);
|
||||
}, [slotUpdatedAt]);
|
||||
|
||||
return (
|
||||
@ -85,7 +83,7 @@ const ProfileDialog = ({ open = false, onClose }: Props): JSX.Element => {
|
||||
)}
|
||||
</Typography>
|
||||
|
||||
{loadingCoordinators > 0 ? (
|
||||
{loadingRobots > 0 ? (
|
||||
<>
|
||||
<b>{t('Looking for your robot!')}</b>
|
||||
<LinearProgress />
|
||||
|
@ -502,7 +502,6 @@ const MakerForm = ({
|
||||
(!makerHasAmountRange && maker.amount <= 0) ||
|
||||
(maker.isExplicit && (maker.badSatoshisText !== '' || maker.satoshis === '')) ||
|
||||
(!maker.isExplicit && maker.badPremiumText !== '') ||
|
||||
federation.getCoordinator(maker.coordinator)?.info === undefined ||
|
||||
federation.getCoordinator(maker.coordinator)?.limits === undefined
|
||||
);
|
||||
}, [maker, amountLimits, federationUpdatedAt, fav.type, makerHasAmountRange]);
|
||||
|
@ -86,7 +86,7 @@ const SelectCoordinator: React.FC<SelectCoordinatorProps> = ({
|
||||
flipHorizontally={false}
|
||||
small={true}
|
||||
/>
|
||||
{(coordinator?.info === undefined ||
|
||||
{(coordinator?.limits === undefined ||
|
||||
Object.keys(coordinator?.limits).length === 0) && (
|
||||
<CircularProgress
|
||||
size={49}
|
||||
|
@ -68,12 +68,12 @@ export const FederationContextProvider = ({
|
||||
useEffect(() => {
|
||||
if (client !== 'mobile' || torStatus === 'ON' || !settings.useProxy) {
|
||||
void federation.updateUrl(origin, settings, hostUrl);
|
||||
void federation.updateMeta();
|
||||
void federation.loadLimits();
|
||||
}
|
||||
}, [settings.network, settings.useProxy, torStatus]);
|
||||
|
||||
useEffect(() => {
|
||||
federation.setConnection(settings.connection);
|
||||
federation.setConnection(settings);
|
||||
}, [settings.connection]);
|
||||
|
||||
const addNewCoordinator: (alias: string, url: string) => void = (alias, url) => {
|
||||
@ -96,7 +96,7 @@ export const FederationContextProvider = ({
|
||||
}
|
||||
federation.addCoordinator(origin, settings, hostUrl, attributes);
|
||||
const newCoordinator: Coordinator = federation.coordinators[alias];
|
||||
newCoordinator.updateMeta(() => {
|
||||
newCoordinator.loadLimits(() => {
|
||||
setCoordinatorUpdatedAt(new Date().toISOString());
|
||||
});
|
||||
garage.syncCoordinator(federation, alias);
|
||||
@ -106,7 +106,7 @@ export const FederationContextProvider = ({
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (page === 'offers') void federation.updateBook();
|
||||
if (page === 'offers') void federation.loadBook();
|
||||
}, [page]);
|
||||
|
||||
// use effects to fetchRobots on Profile open
|
||||
|
@ -182,21 +182,6 @@ export class Coordinator {
|
||||
}
|
||||
};
|
||||
|
||||
updateMeta = async (onUpdate: (shortAlias: string) => void = () => {}): Promise<void> => {
|
||||
const onDataLoad = (): void => {
|
||||
if (this.isUpdated()) onUpdate(this.shortAlias);
|
||||
};
|
||||
|
||||
this.loadLimits(onDataLoad);
|
||||
this.loadInfo(onDataLoad);
|
||||
};
|
||||
|
||||
updateBook = async (onUpdate: (shortAlias: string) => void = () => {}): Promise<void> => {
|
||||
this.loadBook(() => {
|
||||
onUpdate(this.shortAlias);
|
||||
});
|
||||
};
|
||||
|
||||
generateAllMakerAvatars = async (): Promise<void> => {
|
||||
for (const order of Object.values(this.book)) {
|
||||
void roboidentitiesClient.generateRobohash(order.maker_hash_id, 'small');
|
||||
@ -287,7 +272,7 @@ export class Coordinator {
|
||||
|
||||
enable = (onEnabled: () => void = () => {}): void => {
|
||||
this.enabled = true;
|
||||
void this.updateMeta(() => {
|
||||
void this.loadLimits(() => {
|
||||
onEnabled();
|
||||
});
|
||||
};
|
||||
@ -299,10 +284,6 @@ export class Coordinator {
|
||||
this.book = {};
|
||||
};
|
||||
|
||||
isUpdated = (): boolean => {
|
||||
return !((this.loadingBook === this.loadingInfo) === this.loadingLimits);
|
||||
};
|
||||
|
||||
getBaseUrl = (): string => {
|
||||
return this.url + this.basePath;
|
||||
};
|
||||
|
@ -36,20 +36,18 @@ export const updateExchangeInfo = (federation: Federation): ExchangeInfo => {
|
||||
'lifetime_volume',
|
||||
];
|
||||
|
||||
Object.values(federation.coordinators)
|
||||
.filter((coor) => coor.isUpdated())
|
||||
.forEach((coordinator, index) => {
|
||||
if (coordinator.info !== undefined) {
|
||||
premiums[index] = coordinator.info.last_day_nonkyc_btc_premium;
|
||||
volumes[index] = coordinator.info.last_day_volume;
|
||||
highestVersion = getHigherVer(highestVersion, coordinator.info.version);
|
||||
active_robots_today = Math.max(active_robots_today, coordinator.info.active_robots_today);
|
||||
Object.values(federation.coordinators).forEach((coordinator, index) => {
|
||||
if (coordinator.info !== undefined) {
|
||||
premiums[index] = coordinator.info.last_day_nonkyc_btc_premium;
|
||||
volumes[index] = coordinator.info.last_day_volume;
|
||||
highestVersion = getHigherVer(highestVersion, coordinator.info.version);
|
||||
active_robots_today = Math.max(active_robots_today, coordinator.info.active_robots_today);
|
||||
|
||||
aggregations.forEach((key: any) => {
|
||||
info[key] = Number(info[key]) + Number(coordinator.info[key]);
|
||||
});
|
||||
}
|
||||
});
|
||||
aggregations.forEach((key: any) => {
|
||||
info[key] = Number(info[key]) + Number(coordinator.info[key]);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
info.last_day_nonkyc_btc_premium = weightedMean(premiums, volumes);
|
||||
info.version = highestVersion;
|
||||
|
@ -78,18 +78,18 @@ export class Federation {
|
||||
public relayPool: SimplePool = new SimplePool();
|
||||
public relaySubscriptions: SubCloser[] = [];
|
||||
|
||||
setConnection = (connection: 'api' | 'nostr'): void => {
|
||||
this.connection = connection;
|
||||
setConnection = (settings: Settings): void => {
|
||||
this.connection = settings.connection;
|
||||
|
||||
if (this.connection === 'nostr') {
|
||||
this.connectNostr();
|
||||
this.connectNostr(settings);
|
||||
} else {
|
||||
this.relayPool.close(Array.from(this.relayPool.trustedRelayURLs));
|
||||
this.updateBook();
|
||||
this.loadBook();
|
||||
}
|
||||
};
|
||||
|
||||
connectNostr = (): void => {
|
||||
connectNostr = (settings: Settings): void => {
|
||||
this.loading = true;
|
||||
this.book = {};
|
||||
|
||||
@ -105,7 +105,7 @@ export class Federation {
|
||||
{
|
||||
authors,
|
||||
kinds: [38383],
|
||||
'#n': ['mainnet'],
|
||||
'#n': [settings.network],
|
||||
},
|
||||
],
|
||||
{
|
||||
@ -123,12 +123,6 @@ export class Federation {
|
||||
this.updateExchange();
|
||||
this.triggerHook('onFederationUpdate');
|
||||
},
|
||||
onclose: () => {
|
||||
this.exchange.loadingCache = this.exchange.loadingCache - 1;
|
||||
this.loading = this.exchange.loadingCache > 0 && this.exchange.loadingCoordinators > 0;
|
||||
this.updateExchange();
|
||||
this.triggerHook('onFederationUpdate');
|
||||
},
|
||||
},
|
||||
);
|
||||
this.relaySubscriptions.push(sub);
|
||||
@ -186,8 +180,7 @@ export class Federation {
|
||||
systemClient.setCookie('federation', JSON.stringify(federationUrls));
|
||||
};
|
||||
|
||||
updateMeta = async (): Promise<void> => {
|
||||
this.loading = true;
|
||||
loadInfo = async (): Promise<void> => {
|
||||
this.exchange.info = {
|
||||
num_public_buy_orders: 0,
|
||||
num_public_sell_orders: 0,
|
||||
@ -198,19 +191,30 @@ export class Federation {
|
||||
lifetime_volume: 0,
|
||||
version: { major: 0, minor: 0, patch: 0 },
|
||||
};
|
||||
this.updateEnabledCoordinators();
|
||||
|
||||
for (const coor of Object.values(this.coordinators)) {
|
||||
void coor.loadInfo(() => {
|
||||
this.onCoordinatorSaved();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
loadLimits = async (): Promise<void> => {
|
||||
this.loading = true;
|
||||
this.exchange.onlineCoordinators = 0;
|
||||
this.exchange.loadingCoordinators = Object.keys(this.coordinators).length;
|
||||
this.updateEnabledCoordinators();
|
||||
|
||||
for (const coor of Object.values(this.coordinators)) {
|
||||
void coor.updateMeta(() => {
|
||||
void coor.loadLimits(() => {
|
||||
this.exchange.onlineCoordinators = this.exchange.onlineCoordinators + 1;
|
||||
this.onCoordinatorSaved();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
updateBook = async (): Promise<void> => {
|
||||
loadBook = async (): Promise<void> => {
|
||||
if (this.connection !== 'api') return;
|
||||
|
||||
this.loading = true;
|
||||
@ -218,7 +222,7 @@ export class Federation {
|
||||
this.triggerHook('onFederationUpdate');
|
||||
this.exchange.loadingCoordinators = Object.keys(this.coordinators).length;
|
||||
for (const coor of Object.values(this.coordinators)) {
|
||||
void coor.updateBook(() => {
|
||||
void coor.loadBook(() => {
|
||||
this.onCoordinatorSaved();
|
||||
this.triggerHook('onFederationUpdate');
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user