import * as React from 'react'; import { ApiState, DelegationsResponse, UniqDelegationsResponse, MixNodeDescriptionResponse, MixNodeEconomicDynamicsStatsResponse, MixNodeResponseItem, StatsResponse, StatusResponse, UptimeStoryResponse, } from '../typeDefs/explorer-api'; import { Api } from '../api'; import { useApiState } from './hooks'; import { mixNodeResponseItemToMixnodeRowType, MixnodeRowType } from '../components/MixNodes'; /** * This context provides the state for a single mixnode by identity key. */ interface MixnodeState { delegations?: ApiState; uniqDelegations?: ApiState; description?: ApiState; economicDynamicsStats?: ApiState; mixNode?: ApiState; mixNodeRow?: MixnodeRowType; stats?: ApiState; status?: ApiState; uptimeStory?: ApiState; } export const MixnodeContext = React.createContext({}); export const useMixnodeContext = (): React.ContextType => React.useContext(MixnodeContext); interface MixnodeContextProviderProps { mixId: string; children: React.ReactNode; } /** * Provides a state context for a mixnode by identity * @param mixId The mixID of the mixnode */ export const MixnodeContextProvider: FCWithChildren = ({ mixId, children }) => { const [mixNode, fetchMixnodeById, clearMixnodeById] = useApiState( mixId, Api.fetchMixnodeByID, 'Failed to fetch mixnode by id', ); const [mixNodeRow, setMixnodeRow] = React.useState(); const [delegations, fetchDelegations, clearDelegations] = useApiState( mixId, Api.fetchDelegationsById, 'Failed to fetch delegations for mixnode', ); const [uniqDelegations, fetchUniqDelegations, clearUniqDelegations] = useApiState( mixId, Api.fetchUniqDelegationsById, 'Failed to fetch delegations for mixnode', ); const [status, fetchStatus, clearStatus] = useApiState( mixId, Api.fetchStatusById, 'Failed to fetch mixnode status', ); const [stats, fetchStats, clearStats] = useApiState( mixId, Api.fetchStatsById, 'Failed to fetch mixnode stats', ); const [description, fetchDescription, clearDescription] = useApiState( mixId, Api.fetchMixnodeDescriptionById, 'Failed to fetch mixnode description', ); const [economicDynamicsStats, fetchEconomicDynamicsStats, clearEconomicDynamicsStats] = useApiState( mixId, Api.fetchMixnodeEconomicDynamicsStatsById, 'Failed to fetch mixnode dynamics stats by id', ); const [uptimeStory, fetchUptimeHistory, clearUptimeHistory] = useApiState( mixId, Api.fetchUptimeStoryById, 'Failed to fetch mixnode uptime history', ); React.useEffect(() => { // when the identity key changes, remove all previous data clearMixnodeById(); clearDelegations(); clearUniqDelegations(); clearStatus(); clearStats(); clearDescription(); clearEconomicDynamicsStats(); clearUptimeHistory(); // fetch the mixnode, then get all the other stuff fetchMixnodeById().then((value) => { if (!value.data || value.error) { setMixnodeRow(undefined); return; } setMixnodeRow(mixNodeResponseItemToMixnodeRowType(value.data)); Promise.all([ fetchDelegations(), fetchUniqDelegations(), fetchStatus(), fetchStats(), fetchDescription(), fetchEconomicDynamicsStats(), fetchUptimeHistory(), ]); }); }, [mixId]); const state = React.useMemo( () => ({ delegations, uniqDelegations, mixNode, mixNodeRow, description, economicDynamicsStats, stats, status, uptimeStory, }), [ { delegations, uniqDelegations, mixNode, mixNodeRow, description, economicDynamicsStats, stats, status, uptimeStory, }, ], ); return {children}; };