diff --git a/frontend/src/basic/RobotPage/index.tsx b/frontend/src/basic/RobotPage/index.tsx index a58e7c2b..ed4ec6eb 100644 --- a/frontend/src/basic/RobotPage/index.tsx +++ b/frontend/src/basic/RobotPage/index.tsx @@ -65,11 +65,10 @@ const RobotPage = (): JSX.Element => { setInputToken(token); genKey(token) .then((key) => { - garage.createRobot(token, sortedCoordinators[0], { + garage.createRobot(token, sortedCoordinators, { token, pubKey: key.publicKeyArmored, encPrivKey: key.encryptedPrivateKeyArmored, - shortAlias: sortedCoordinators[0], }); void federation.fetchRobot(garage, token); garage.currentSlot = token; diff --git a/frontend/src/components/BookTable/index.tsx b/frontend/src/components/BookTable/index.tsx index e10da1f3..1eef748f 100644 --- a/frontend/src/components/BookTable/index.tsx +++ b/frontend/src/components/BookTable/index.tsx @@ -113,9 +113,6 @@ const BookTable = ({ const { t } = useTranslation(); const theme = useTheme(); const orders = orderList ?? federation.book; - const loadingProgress = useMemo(() => { - return (federation.exchange.onlineCoordinators / federation.exchange.totalCoordinators) * 100; - }, [coordinatorUpdatedAt]); const [paginationModel, setPaginationModel] = useState({ pageSize: 0, @@ -942,7 +939,11 @@ const BookTable = ({ }, loadingOverlay: { variant: 'determinate', - value: loadingProgress, + value: + ((federation.exchange.enabledCoordinators - + federation.exchange.loadingCoordinators) / + federation.exchange.enabledCoordinators) * + 100, }, }} paginationModel={paginationModel} diff --git a/frontend/src/models/Exchange.model.ts b/frontend/src/models/Exchange.model.ts index 7dee35b8..9e783ac6 100644 --- a/frontend/src/models/Exchange.model.ts +++ b/frontend/src/models/Exchange.model.ts @@ -61,13 +61,17 @@ export const updateExchangeInfo = (federation: Federation): ExchangeInfo => { export interface Exchange { info: ExchangeInfo; + enabledCoordinators: number; onlineCoordinators: number; + loadingCoordinators: number; totalCoordinators: number; } export const defaultExchange: Exchange = { info: defaultExchangeInfo, + enabledCoordinators: 0, onlineCoordinators: 0, + loadingCoordinators: 0, totalCoordinators: 0, }; diff --git a/frontend/src/models/Federation.model.ts b/frontend/src/models/Federation.model.ts index f5effe87..a5cbcf75 100644 --- a/frontend/src/models/Federation.model.ts +++ b/frontend/src/models/Federation.model.ts @@ -61,8 +61,10 @@ export class Federation { this.book = Object.values(this.coordinators).reduce((array, coordinator) => { return [...array, ...coordinator.book]; }, []); - this.loading = false; this.triggerHook('onCoordinatorUpdate'); + this.exchange.loadingCoordinators = + this.exchange.loadingCoordinators < 1 ? 0 : this.exchange.loadingCoordinators - 1; + this.loading = this.exchange.loadingCoordinators > 0; if (Object.values(this.coordinators).every((coor) => coor.isUpdated())) { this.updateExchange(); this.triggerHook('onFederationReady'); @@ -76,9 +78,13 @@ export class Federation { this.onCoordinatorSaved(); }; this.loading = true; + this.exchange.loadingCoordinators = Object.keys(this.coordinators).length; for (const coor of Object.values(this.coordinators)) { - await coor.start(origin, settings, hostUrl, onCoordinatorStarted); + if (coor.enabled) { + await coor.start(origin, settings, hostUrl, onCoordinatorStarted); + } } + this.updateEnabledCoordinators(); }; // On Testnet/Mainnet change @@ -87,10 +93,12 @@ export class Federation { for (const coor of Object.values(this.coordinators)) { await coor.updateUrl(settings, origin, hostUrl); } + this.loading = false; }; update = async (): Promise => { - this.loading = false; + this.loading = true; + this.exchange.loadingCoordinators = Object.keys(this.coordinators).length; for (const coor of Object.values(this.coordinators)) { await coor.update(() => { this.onCoordinatorSaved(); @@ -99,7 +107,8 @@ export class Federation { }; updateBook = async (): Promise => { - this.loading = false; + this.loading = true; + this.exchange.loadingCoordinators = Object.keys(this.coordinators).length; for (const coor of Object.values(this.coordinators)) { await coor.updateBook(() => { this.onCoordinatorSaved(); @@ -125,14 +134,22 @@ export class Federation { disableCoordinator = (shortAlias: string): void => { this.coordinators[shortAlias].disable(); + this.updateEnabledCoordinators(); this.triggerHook('onCoordinatorUpdate'); }; enableCoordinator = (shortAlias: string): void => { this.coordinators[shortAlias].enable(() => { + this.updateEnabledCoordinators(); this.triggerHook('onCoordinatorUpdate'); }); }; + + updateEnabledCoordinators = (): void => { + this.exchange.enabledCoordinators = Object.values(this.coordinators).filter( + (c) => c.enabled, + ).length; + }; } export default Federation; diff --git a/frontend/src/models/Garage.model.ts b/frontend/src/models/Garage.model.ts index 3c97d266..3ff38879 100644 --- a/frontend/src/models/Garage.model.ts +++ b/frontend/src/models/Garage.model.ts @@ -59,10 +59,13 @@ class Garage { const rawSlots = JSON.parse(slotsDump); Object.values(rawSlots).forEach((rawSlot: Record) => { if (rawSlot?.token) { + this.slots[rawSlot.token] = new Slot(rawSlot.token, Object.keys(rawSlot.robots), {}); + Object.keys(rawSlot.robots).forEach((shortAlias) => { const rawRobot = rawSlot.robots[shortAlias]; - this.createRobot(rawRobot.token, shortAlias, rawRobot); + this.updateRobot(rawSlot.token, shortAlias, rawRobot); }); + this.currentSlot = rawSlot?.token; } }); @@ -102,16 +105,15 @@ class Garage { }; // Robots - createRobot: (token: string, shortAlias: string, attributes: Record) => void = ( + createRobot: (token: string, shortAliases: string[], attributes: Record) => void = ( token, - shortAlias, + shortAliases, attributes, ) => { - if (!token || !shortAlias) return; + if (!token || !shortAliases) return; if (this.getSlot(token) === null) { - this.slots[token] = new Slot(token); - this.slots[token]?.createRobot(shortAlias, attributes); + this.slots[token] = new Slot(token, shortAliases, attributes); this.save(); this.triggerHook('onRobotUpdate'); } diff --git a/frontend/src/models/Slot.model.ts b/frontend/src/models/Slot.model.ts index c0585fd5..864820ed 100644 --- a/frontend/src/models/Slot.model.ts +++ b/frontend/src/models/Slot.model.ts @@ -4,7 +4,7 @@ import { robohash } from '../components/RobotAvatar/RobohashGenerator'; import { generate_roboname } from 'robo-identities-wasm'; class Slot { - constructor(token: string) { + constructor(token: string, shortAliases: string[], robotAttributes: Record) { this.token = token; this.hashId = sha256(sha256(this.token)); @@ -13,7 +13,10 @@ class Slot { void robohash.generate(this.hashId, 'small'); void robohash.generate(this.hashId, 'large'); - this.robots = {}; + this.robots = shortAliases.reduce((acc: Record, shortAlias: string) => { + acc[shortAlias] = new Robot(robotAttributes); + return acc; + }, {}); this.order = null; this.activeShortAlias = null; @@ -47,25 +50,16 @@ class Slot { return null; }; - createRobot = (shortAlias: string, attributes: Record): Robot | null => { - if (this.robots[shortAlias] === undefined) { - this.robots[shortAlias] = new Robot(attributes ?? {}); - return this.robots[shortAlias]; - } - - return null; - }; - updateRobot = (shortAlias: string, attributes: Record): Robot | null => { this.robots[shortAlias].update(attributes); - if (attributes.lastOrderId !== undefined && attributes.lastOrderId != null) { + if (attributes.lastOrderId) { this.lastShortAlias = shortAlias; if (this.activeShortAlias === shortAlias) { this.activeShortAlias = null; } } - if (attributes.activeOrderId !== undefined && attributes.activeOrderId != null) { + if (attributes.activeOrderId) { this.activeShortAlias = attributes.shortAlias; }