mirror of
https://github.com/RoboSats/robosats.git
synced 2025-07-17 00:03:13 +00:00
Improve client performance
This commit is contained in:
@ -4,9 +4,14 @@ import FederationTable from '../../components/FederationTable';
|
||||
import { t } from 'i18next';
|
||||
import { FederationContext, type UseFederationStoreType } from '../../contexts/FederationContext';
|
||||
import { GarageContext, type UseGarageStoreType } from '../../contexts/GarageContext';
|
||||
import { Garage } from '../../models';
|
||||
import { Origin, Origins } from '../../models/Coordinator.model';
|
||||
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
|
||||
|
||||
const Coordinators = (): React.JSX.Element => {
|
||||
const { federation, addNewCoordinator } = useContext<UseFederationStoreType>(FederationContext);
|
||||
const { settings, origin, hostUrl } = useContext<UseAppStoreType>(AppContext);
|
||||
const { federation, setFederationUpdatedAt } =
|
||||
useContext<UseFederationStoreType>(FederationContext);
|
||||
const { garage } = useContext<UseGarageStoreType>(GarageContext);
|
||||
const [newAlias, setNewAlias] = useState<string>('');
|
||||
const [newUrl, setNewUrl] = useState<string>('');
|
||||
@ -15,6 +20,34 @@ const Coordinators = (): React.JSX.Element => {
|
||||
// Regular expression to match a valid .onion URL
|
||||
const onionUrlPattern = /^((http|https):\/\/)?[a-zA-Z2-7]{16,56}\.onion$\/?/;
|
||||
|
||||
const addNewCoordinator: (alias: string, garage: Garage, url: string) => void = (
|
||||
alias,
|
||||
garage,
|
||||
url,
|
||||
) => {
|
||||
if (!federation.getCoordinator(alias)) {
|
||||
const attributes: object = {
|
||||
longAlias: alias,
|
||||
shortAlias: alias,
|
||||
federated: false,
|
||||
enabled: true,
|
||||
};
|
||||
const origins: Origins = {
|
||||
clearnet: undefined,
|
||||
onion: url as Origin,
|
||||
i2p: undefined,
|
||||
};
|
||||
if (settings.network === 'mainnet') {
|
||||
attributes.mainnet = origins;
|
||||
} else {
|
||||
attributes.testnet = origins;
|
||||
}
|
||||
federation.addCoordinator(origin, settings, hostUrl, attributes);
|
||||
garage.syncCoordinator(federation, alias);
|
||||
setFederationUpdatedAt(new Date().toISOString());
|
||||
}
|
||||
};
|
||||
|
||||
const addCoordinator: () => void = () => {
|
||||
if (federation.getCoordinator(newAlias)) {
|
||||
setError(t('Alias already exists'));
|
||||
@ -24,7 +57,7 @@ const Coordinators = (): React.JSX.Element => {
|
||||
if (!/^((http|https):\/\/)/.test(fullNewUrl)) {
|
||||
fullNewUrl = `http://${newUrl}`;
|
||||
}
|
||||
addNewCoordinator(newAlias, fullNewUrl);
|
||||
addNewCoordinator(newAlias, garage, fullNewUrl);
|
||||
garage.syncCoordinator(federation, newAlias);
|
||||
setNewAlias('');
|
||||
setNewUrl('');
|
||||
|
@ -343,11 +343,9 @@ const BookTable = ({
|
||||
flex: 2,
|
||||
renderCell: (params: { row: PublicOrder }) => {
|
||||
const currencyCode = String(currencyDict[params.row.currency.toString()]);
|
||||
const coordinator =
|
||||
federation.getCoordinator(params.row.coordinatorShortAlias) ??
|
||||
federation.getCoordinators()[0];
|
||||
const limits = federation.getLimits(params.row.coordinatorShortAlias);
|
||||
const premium = parseFloat(params.row.premium);
|
||||
const limitPrice = coordinator.limits[params.row.currency.toString()]?.price;
|
||||
const limitPrice = limits[params.row.currency.toString()]?.price;
|
||||
const price = (limitPrice ?? 1) * (1 + premium / 100);
|
||||
|
||||
return (
|
||||
@ -501,16 +499,13 @@ const BookTable = ({
|
||||
type: 'number',
|
||||
flex: 1,
|
||||
renderCell: (params: { row: PublicOrder }) => {
|
||||
const coordinator =
|
||||
federation.getCoordinator(params.row.coordinatorShortAlias) ??
|
||||
federation.getCoordinators()[0];
|
||||
const limits = federation.getLimits(params.row.coordinatorShortAlias);
|
||||
const amount =
|
||||
params.row.has_range === true
|
||||
? parseFloat(params.row.max_amount)
|
||||
: parseFloat(params.row.amount);
|
||||
const premium = parseFloat(params.row.premium);
|
||||
const price =
|
||||
(coordinator.limits[params.row.currency.toString()]?.price ?? 1) * (1 + premium / 100);
|
||||
const price = (limits[params.row.currency.toString()]?.price ?? 1) * (1 + premium / 100);
|
||||
const satoshisNow = (100000000 * amount) / price;
|
||||
|
||||
return (
|
||||
|
@ -388,7 +388,7 @@ const CoordinatorDialog = ({ open = false, onClose, shortAlias }: Props): React.
|
||||
coordinator.shortAlias,
|
||||
);
|
||||
}
|
||||
coordinator?.loadInfo();
|
||||
if (!coordinator.info) coordinator?.loadInfo();
|
||||
}
|
||||
}, [open]);
|
||||
|
||||
|
@ -57,6 +57,7 @@ const FederationTable = ({
|
||||
const mobile = windowSize.width < 44;
|
||||
|
||||
useEffect(() => {
|
||||
federation.loadInfo();
|
||||
loadRatings();
|
||||
}, []);
|
||||
|
||||
@ -240,7 +241,7 @@ const FederationTable = ({
|
||||
onClickCoordinator(params.row.shortAlias);
|
||||
}}
|
||||
>
|
||||
{Boolean(params.row.loadingLimits) && Boolean(params.row.enabled) ? (
|
||||
{Boolean(params.row.loadingInfo) && Boolean(params.row.enabled) ? (
|
||||
<CircularProgress thickness={0.35 * fontSize} size={1.5 * fontSize} />
|
||||
) : params.row.limits !== undefined ? (
|
||||
<Link color='success' />
|
||||
|
@ -86,31 +86,26 @@ const MakerForm = ({
|
||||
|
||||
const amountSafeThresholds = [1.03, 0.98];
|
||||
|
||||
useEffect(() => {
|
||||
federation
|
||||
.loadInfo()
|
||||
.then(() => {})
|
||||
.catch((error) => {
|
||||
console.error('Error loading info:', error);
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setCurrencyCode(currencyDict[fav.currency === 0 ? 1 : fav.currency]);
|
||||
}, [federationUpdatedAt]);
|
||||
|
||||
useEffect(() => {
|
||||
updateCoordinatorInfo();
|
||||
}, [maker.coordinator, federationUpdatedAt]);
|
||||
}, [maker.coordinator]);
|
||||
|
||||
const updateCoordinatorInfo = (): void => {
|
||||
if (maker.coordinator != null) {
|
||||
const newLimits = federation.getCoordinator(maker.coordinator)?.limits;
|
||||
if (newLimits && Object.keys(newLimits).length !== 0) {
|
||||
updateAmountLimits(newLimits, fav.currency, maker.premium);
|
||||
updateCurrentPrice(newLimits, fav.currency, maker.premium);
|
||||
setLimits(newLimits);
|
||||
}
|
||||
const coordinator = federation.getCoordinator(maker.coordinator);
|
||||
coordinator.loadInfo();
|
||||
coordinator.loadLimits(() => {
|
||||
const newLimits = coordinator.limits;
|
||||
if (newLimits && Object.keys(newLimits).length !== 0) {
|
||||
updateAmountLimits(newLimits, fav.currency, maker.premium);
|
||||
updateCurrentPrice(newLimits, fav.currency, maker.premium);
|
||||
setLimits(newLimits);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -102,8 +102,7 @@ const SelectCoordinator: React.FC<SelectCoordinatorProps> = ({
|
||||
flipHorizontally={false}
|
||||
small={true}
|
||||
/>
|
||||
{(coordinator?.limits === undefined ||
|
||||
Object.keys(coordinator?.limits).length === 0) && (
|
||||
{(coordinator?.loadingInfo || coordinator?.loadingLimits) && (
|
||||
<CircularProgress
|
||||
size={49}
|
||||
thickness={5}
|
||||
|
@ -4,8 +4,6 @@ import { Federation, Settings } from '../models';
|
||||
|
||||
import { AppContext, type UseAppStoreType } from './AppContext';
|
||||
import { GarageContext, type UseGarageStoreType } from './GarageContext';
|
||||
import type Coordinator from '../models/Coordinator.model';
|
||||
import { type Origin, type Origins } from '../models/Coordinator.model';
|
||||
|
||||
export interface CurrentOrderIdProps {
|
||||
id: number | null;
|
||||
@ -18,18 +16,16 @@ export interface FederationContextProviderProps {
|
||||
|
||||
export interface UseFederationStoreType {
|
||||
federation: Federation;
|
||||
coordinatorUpdatedAt: string;
|
||||
federationUpdatedAt: string;
|
||||
addNewCoordinator: (alias: string, url: string) => void;
|
||||
setFederationUpdatedAt: (federationUpdatedAt: string) => void;
|
||||
}
|
||||
|
||||
const initialFederation = new Federation('onion', new Settings(), '');
|
||||
|
||||
export const initialFederationContext: UseFederationStoreType = {
|
||||
federation: initialFederation,
|
||||
coordinatorUpdatedAt: '',
|
||||
federationUpdatedAt: '',
|
||||
addNewCoordinator: () => {},
|
||||
setFederationUpdatedAt: () => {},
|
||||
};
|
||||
|
||||
export const FederationContext = createContext<UseFederationStoreType>(initialFederationContext);
|
||||
@ -37,13 +33,10 @@ export const FederationContext = createContext<UseFederationStoreType>(initialFe
|
||||
export const FederationContextProvider = ({
|
||||
children,
|
||||
}: FederationContextProviderProps): React.JSX.Element => {
|
||||
const { settings, page, origin, hostUrl, open, torStatus, client, fav } =
|
||||
const { settings, page, origin, hostUrl, torStatus, client, fav } =
|
||||
useContext<UseAppStoreType>(AppContext);
|
||||
const { setMaker, garage } = useContext<UseGarageStoreType>(GarageContext);
|
||||
const { setMaker } = useContext<UseGarageStoreType>(GarageContext);
|
||||
const [federation] = useState(initialFederationContext.federation);
|
||||
const [coordinatorUpdatedAt, setCoordinatorUpdatedAt] = useState<string>(
|
||||
new Date().toISOString(),
|
||||
);
|
||||
const [federationUpdatedAt, setFederationUpdatedAt] = useState<string>(new Date().toISOString());
|
||||
|
||||
useEffect(() => {
|
||||
@ -61,54 +54,16 @@ export const FederationContextProvider = ({
|
||||
}
|
||||
}, [settings.network, settings.useProxy, torStatus, settings.connection]);
|
||||
|
||||
const addNewCoordinator: (alias: string, url: string) => void = (alias, url) => {
|
||||
if (!federation.getCoordinator(alias)) {
|
||||
const attributes: object = {
|
||||
longAlias: alias,
|
||||
shortAlias: alias,
|
||||
federated: false,
|
||||
enabled: true,
|
||||
};
|
||||
const origins: Origins = {
|
||||
clearnet: undefined,
|
||||
onion: url as Origin,
|
||||
i2p: undefined,
|
||||
};
|
||||
if (settings.network === 'mainnet') {
|
||||
attributes.mainnet = origins;
|
||||
} else {
|
||||
attributes.testnet = origins;
|
||||
}
|
||||
federation.addCoordinator(origin, settings, hostUrl, attributes);
|
||||
const newCoordinator: Coordinator = federation.getCoordinator(alias);
|
||||
newCoordinator.loadLimits(() => {
|
||||
setCoordinatorUpdatedAt(new Date().toISOString());
|
||||
});
|
||||
garage.syncCoordinator(federation, alias);
|
||||
setFederationUpdatedAt(new Date().toISOString());
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (page === 'offers') void federation.loadBook();
|
||||
}, [page]);
|
||||
|
||||
// use effects to fetchRobots on Profile open
|
||||
useEffect(() => {
|
||||
const slot = garage.getSlot();
|
||||
|
||||
if (open.profile && slot?.hashId && slot?.token) {
|
||||
void garage.fetchRobot(federation, slot?.token); // refresh/update existing robot
|
||||
}
|
||||
}, [open.profile]);
|
||||
|
||||
return (
|
||||
<FederationContext.Provider
|
||||
value={{
|
||||
federation,
|
||||
coordinatorUpdatedAt,
|
||||
federationUpdatedAt,
|
||||
addNewCoordinator,
|
||||
setFederationUpdatedAt,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import {
|
||||
Coordinator,
|
||||
type Exchange,
|
||||
LimitList,
|
||||
type Origin,
|
||||
type PublicOrder,
|
||||
type Settings,
|
||||
@ -90,7 +91,7 @@ export class Federation {
|
||||
coordinators.forEach((c) => c.updateUrl(origin, settings, hostUrl));
|
||||
this.roboPool.updateRelays(hostUrl, Object.values(this.coordinators));
|
||||
|
||||
void this.loadLimits();
|
||||
coordinators[0].loadLimits();
|
||||
|
||||
if (this.connection === 'nostr') {
|
||||
this.loadBookNostr(coordinator !== 'any');
|
||||
@ -194,20 +195,6 @@ export class Federation {
|
||||
}
|
||||
};
|
||||
|
||||
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)) {
|
||||
coor.loadLimits(() => {
|
||||
this.exchange.onlineCoordinators = this.exchange.onlineCoordinators + 1;
|
||||
this.onCoordinatorSaved();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
loadBook = async (): Promise<void> => {
|
||||
if (this.connection !== 'api') return;
|
||||
|
||||
@ -229,6 +216,18 @@ export class Federation {
|
||||
this.triggerHook('onFederationUpdate');
|
||||
};
|
||||
|
||||
getLimits = (shortAlias: string): LimitList => {
|
||||
console.log('shortAlias', shortAlias);
|
||||
let limits = this.coordinators[shortAlias]?.limits || {};
|
||||
|
||||
console.log('limits pre', Object.keys(limits).length);
|
||||
if (Object.keys(limits).length === 0) {
|
||||
limits = this.getCoordinators()[0]?.limits;
|
||||
}
|
||||
console.log('limits', Object.keys(limits).length);
|
||||
return limits;
|
||||
};
|
||||
|
||||
// Coordinators
|
||||
getCoordinators = (): Coordinator[] => {
|
||||
return Object.values(this.coordinators);
|
||||
|
Reference in New Issue
Block a user