diff --git a/frontend/src/basic/MakerPage/index.tsx b/frontend/src/basic/MakerPage/index.tsx index d7be7fdd..1424b366 100644 --- a/frontend/src/basic/MakerPage/index.tsx +++ b/frontend/src/basic/MakerPage/index.tsx @@ -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(AppContext); + const { fav, windowSize, navbarHeight, page } = useContext(AppContext); const { federation } = useContext(FederationContext); const { garage, maker } = useContext(GarageContext); const { t } = useTranslation(); diff --git a/frontend/src/basic/RobotPage/RobotProfile.tsx b/frontend/src/basic/RobotPage/RobotProfile.tsx index cbb2e385..a5f580d6 100644 --- a/frontend/src/basic/RobotPage/RobotProfile.tsx +++ b/frontend/src/basic/RobotPage/RobotProfile.tsx @@ -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(AppContext); const { garage, slotUpdatedAt } = useContext(GarageContext); + const { federation } = useContext(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 ( - {loadingCoordinators > 0 && !slot?.activeOrder?.id ? ( + {federation.loading && !slot?.activeOrder?.id ? ( {t('Looking for orders!')} @@ -208,7 +206,7 @@ const RobotProfile = ({ ) : null} - {!slot?.activeOrder && !slot?.lastOrder && loadingCoordinators === 0 ? ( + {!slot?.activeOrder && !slot?.lastOrder && !federation.loading ? ( {t('No existing orders found')} ) : null} diff --git a/frontend/src/basic/SettingsPage/index.tsx b/frontend/src/basic/SettingsPage/index.tsx index 177ccffe..d131af12 100644 --- a/frontend/src/basic/SettingsPage/index.tsx +++ b/frontend/src/basic/SettingsPage/index.tsx @@ -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(AppContext); + const { windowSize, navbarHeight, page } = useContext(AppContext); const { federation, addNewCoordinator } = useContext(FederationContext); const { garage } = useContext(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 ( { - void federation.updateBook(); + void federation.loadBook(); }} > @@ -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 ( (FederationContext); - const coordinator = federation.getCoordinator(shortAlias ?? ''); const [expanded, setExpanded] = useState<'summary' | 'stats' | 'policies' | undefined>(undefined); + const [coordinator, setCoordinator] = useState( + 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 ( - + {String(coordinator?.longAlias)} @@ -483,7 +494,7 @@ const CoordinatorDialog = ({ open = false, onClose, shortAlias }: Props): JSX.El - {coordinator?.loadingInfo ? ( + {!coordinator || coordinator?.loadingInfo ? ( diff --git a/frontend/src/components/Dialogs/Exchange.tsx b/frontend/src/components/Dialogs/Exchange.tsx index 3ea20200..cbf616b1 100644 --- a/frontend/src/components/Dialogs/Exchange.tsx +++ b/frontend/src/components/Dialogs/Exchange.tsx @@ -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(0); - - useEffect(() => { - const loadedCoordinators = - federation.exchange.enabledCoordinators - federation.exchange.loadingCoordinators; - setLoadingProgress((loadedCoordinators / federation.exchange.enabledCoordinators) * 100); - }, [open, federationUpdatedAt]); return ( -
- +
+
diff --git a/frontend/src/components/Dialogs/Profile.tsx b/frontend/src/components/Dialogs/Profile.tsx index 192533f6..c784b223 100644 --- a/frontend/src/components/Dialogs/Profile.tsx +++ b/frontend/src/components/Dialogs/Profile.tsx @@ -33,15 +33,13 @@ const ProfileDialog = ({ open = false, onClose }: Props): JSX.Element => { const slot = garage.getSlot(); const [loading, setLoading] = useState(true); - const [loadingCoordinators, setLoadingCoordinators] = useState( + const [loadingRobots, setLoadingRobots] = useState( 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 => { )} - {loadingCoordinators > 0 ? ( + {loadingRobots > 0 ? ( <> {t('Looking for your robot!')} diff --git a/frontend/src/components/MakerForm/MakerForm.tsx b/frontend/src/components/MakerForm/MakerForm.tsx index 42b256f8..17913fa0 100644 --- a/frontend/src/components/MakerForm/MakerForm.tsx +++ b/frontend/src/components/MakerForm/MakerForm.tsx @@ -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]); diff --git a/frontend/src/components/MakerForm/SelectCoordinator.tsx b/frontend/src/components/MakerForm/SelectCoordinator.tsx index 9a117a6c..49bb1a1b 100644 --- a/frontend/src/components/MakerForm/SelectCoordinator.tsx +++ b/frontend/src/components/MakerForm/SelectCoordinator.tsx @@ -86,7 +86,7 @@ const SelectCoordinator: React.FC = ({ flipHorizontally={false} small={true} /> - {(coordinator?.info === undefined || + {(coordinator?.limits === undefined || Object.keys(coordinator?.limits).length === 0) && ( { 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 diff --git a/frontend/src/models/Coordinator.model.ts b/frontend/src/models/Coordinator.model.ts index 40e6711c..28a6e8af 100644 --- a/frontend/src/models/Coordinator.model.ts +++ b/frontend/src/models/Coordinator.model.ts @@ -182,21 +182,6 @@ export class Coordinator { } }; - updateMeta = async (onUpdate: (shortAlias: string) => void = () => {}): Promise => { - const onDataLoad = (): void => { - if (this.isUpdated()) onUpdate(this.shortAlias); - }; - - this.loadLimits(onDataLoad); - this.loadInfo(onDataLoad); - }; - - updateBook = async (onUpdate: (shortAlias: string) => void = () => {}): Promise => { - this.loadBook(() => { - onUpdate(this.shortAlias); - }); - }; - generateAllMakerAvatars = async (): Promise => { 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; }; diff --git a/frontend/src/models/Exchange.model.ts b/frontend/src/models/Exchange.model.ts index 4eb488e7..9943bb69 100644 --- a/frontend/src/models/Exchange.model.ts +++ b/frontend/src/models/Exchange.model.ts @@ -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; diff --git a/frontend/src/models/Federation.model.ts b/frontend/src/models/Federation.model.ts index 94f79b39..ee20da45 100644 --- a/frontend/src/models/Federation.model.ts +++ b/frontend/src/models/Federation.model.ts @@ -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 => { - this.loading = true; + loadInfo = async (): Promise => { 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 => { + 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 => { + loadBook = async (): Promise => { 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'); });