Skip to content

Commit

Permalink
Merge pull request polkadot-cloud#1425 from paritytech/rb-member-coun…
Browse files Browse the repository at this point in the history
…t-to-context

Move memberCount to context
  • Loading branch information
Ross Bulat authored Sep 14, 2023
2 parents 7eb5cf7 + 5838f57 commit 200f0cd
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 77 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
"@fortawesome/react-fontawesome": "^0.2.0",
"@ledgerhq/hw-transport-webhid": "^6.27.19",
"@polkadot-cloud/community": "0.1.11",
"@polkadot-cloud/core": "^0.1.19",
"@polkadot-cloud/react": "^0.1.37",
"@polkadot-cloud/core": "^0.1.20",
"@polkadot-cloud/react": "^0.1.39",
"@polkadot-cloud/utils": "^0.0.11",
"@polkadot/api": "^10.9.1",
"@polkadot/keyring": "^12.1.1",
Expand Down
4 changes: 2 additions & 2 deletions src/Providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,15 @@ import { OverlayProvider } from '@polkadot-cloud/react';
export const Providers = withProviders(
FiltersProvider,
NotificationsProvider,
PluginsProvider,
APIProvider,
VaultHardwareProvider,
LedgerHardwareProvider,
ExtensionsProvider,
ConnectProvider,
HelpProvider,
NetworkMetricsProvider,
SubscanProvider,
IdentitiesProvider,
ProxiesProvider,
BalancesProvider,
Expand All @@ -66,9 +68,7 @@ export const Providers = withProviders(
FastUnstakeProvider,
PayoutsProvider,
UIProvider,
PluginsProvider,
SetupProvider,
SubscanProvider,
MenuProvider,
TooltipProvider,
TxMetaProvider,
Expand Down
1 change: 1 addition & 0 deletions src/contexts/Pools/ActivePools/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,5 @@ export const defaultActivePoolContext: ActivePoolsContextState = {
targets,
poolNominations,
synced: 'unsynced',
selectedPoolMemberCount: 0,
};
67 changes: 54 additions & 13 deletions src/contexts/Pools/ActivePools/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,32 @@ import type {
import { useStaking } from 'contexts/Staking';
import type { AnyApi, AnyJson, Sync } from 'types';
import { useEffectIgnoreInitial } from '@polkadot-cloud/react/hooks';
import { useSubscan } from 'contexts/Subscan';
import { usePlugins } from 'contexts/Plugins';
import { useApi } from '../../Api';
import { useConnect } from '../../Connect';
import { useBondedPools } from '../BondedPools';
import { usePoolMemberships } from '../PoolMemberships';
import { usePoolsConfig } from '../PoolsConfig';
import * as defaults from './defaults';
import { usePoolMembers } from '../PoolMembers';

export const ActivePoolsProvider = ({
children,
}: {
children: React.ReactNode;
}) => {
const { eraStakers } = useStaking();
const { pluginEnabled } = usePlugins();
const { activeAccount } = useConnect();
const { fetchPoolDetails } = useSubscan();
const { api, network, isReady } = useApi();
const { membership } = usePoolMemberships();
const { createAccounts } = usePoolsConfig();
const { getAccountPools, bondedPools } = useBondedPools();
const { getMembersOfPoolFromNode, poolMembersNode } = usePoolMembers();

// determine active pools to subscribe to.
// Determine active pools to subscribe to.
const accountPools = useMemo(() => {
const newAccountPools = Object.keys(getAccountPools(activeAccount) || {});
const p = membership?.poolId ? String(membership.poolId) : '-1';
Expand All @@ -42,34 +48,39 @@ export const ActivePoolsProvider = ({
return newAccountPools;
}, [activeAccount, bondedPools, membership]);

// stores member's active pools
// Stores member's active pools.
const [activePools, setActivePools] = useState<ActivePool[]>([]);
const activePoolsRef = useRef(activePools);

// store active pools unsubs
// Store active pools unsubs.
const unsubActivePools = useRef<AnyApi[]>([]);

// store active pools nominations.
// Store active pools nominations.
const [poolNominations, setPoolNominations] = useState<
Record<number, AnyJson>
>({});
const poolNominationsRef = useRef(poolNominations);

// store pool nominations unsubs
// Store pool nominations unsubs.
const unsubNominations = useRef<AnyApi[]>([]);

// store account target validators
// Store account target validators.
const [targets, setTargetsState] = useState<Record<number, AnyJson>>({});
const targetsRef = useRef(targets);

// store whether active pool data has been synced.
// this will be true if no active pool exists for the active account.
// We just need confirmation this is the case.
// Store the member count of the selected pool.
const [selectedPoolMemberCount, setSelectedPoolMemberCount] =
useState<number>(0);

const fetchingMemberCount = useRef<boolean>(false);

// Store whether active pool data has been synced. this will be true if no active pool exists for
// the active account. We just need confirmation this is the case.
const [synced, setSynced] = useState<Sync>('unsynced');
const syncedRef = useRef(synced);

// store the currently selected active pool for the UI.
// Should default to the membership pool (if present).
// Store the currently selected active pool for the UI. Should default to the membership pool (if
// present).
const [selectedPoolId, setSelectedPoolId] = useState<string | null>(null);

const getActivePoolMembership = () =>
Expand Down Expand Up @@ -108,7 +119,7 @@ export const ActivePoolsProvider = ({
}
};

// unsubscribe and reset poolNominations
// Unsubscribe and reset poolNominations.
const unsubscribePoolNominations = () => {
if (unsubNominations.current.length) {
for (const unsub of unsubNominations.current) {
Expand All @@ -119,7 +130,7 @@ export const ActivePoolsProvider = ({
unsubNominations.current = [];
};

// unsubscribe and reset activePool and poolNominations
// Unsubscribe and reset activePool and poolNominations.
const unsubscribeActivePools = () => {
if (unsubActivePools.current.length) {
for (const unsub of unsubActivePools.current) {
Expand Down Expand Up @@ -478,6 +489,29 @@ export const ActivePoolsProvider = ({
membership,
]);

// Gets the member count of the currently selected pool. If Subscan is enabled, it is used instead of the connected node.
const getMemberCount = async () => {
const selectedActivePool = getSelectedActivePool();

if (!selectedActivePool?.id) {
setSelectedPoolMemberCount(0);
return;
}
// If `Subscan` plugin is enabled, fetch member count directly from the API.
if (pluginEnabled('subscan') && !fetchingMemberCount.current) {
fetchingMemberCount.current = true;
const poolDetails = await fetchPoolDetails(selectedActivePool.id);
fetchingMemberCount.current = false;
setSelectedPoolMemberCount(poolDetails?.member_count || 0);
return;
}
// If no plugin available, fetch all pool members from RPC and filter them to determine current
// pool member count. NOTE: Expensive operation.
setSelectedPoolMemberCount(
getMembersOfPoolFromNode(selectedActivePool?.id ?? 0).length
);
};

// when we are subscribed to all active pools, syncing is considered
// completed.
useEffectIgnoreInitial(() => {
Expand All @@ -486,6 +520,12 @@ export const ActivePoolsProvider = ({
}
}, [accountPools, unsubNominations.current]);

// Fetch pool member count. We use `membership` as a dependency as the member count could change
// in the UI when active account's membership changes.
useEffect(() => {
getMemberCount();
}, [activeAccount, getSelectedActivePool(), membership, poolMembersNode]);

return (
<ActivePoolsContext.Provider
value={{
Expand All @@ -505,6 +545,7 @@ export const ActivePoolsProvider = ({
selectedActivePool: getSelectedActivePool(),
targets: getSelectedPoolTargets(),
poolNominations: getSelectedPoolNominations(),
selectedPoolMemberCount,
}}
>
{children}
Expand Down
1 change: 1 addition & 0 deletions src/contexts/Pools/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ export interface ActivePoolsContextState {
targets: any;
poolNominations: any;
synced: Sync;
selectedPoolMemberCount: number;
}

// PoolMembers types
Expand Down
9 changes: 5 additions & 4 deletions src/pages/Pools/Home/Members.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@ import { CardWrapper } from 'library/Card/Wrappers';
import { MembersList as DefaultMemberList } from './MembersList/Default';
import { MembersList as FetchPageMemberList } from './MembersList/FetchPage';

export const Members = ({ memberCount }: { memberCount: number }) => {
export const Members = () => {
const { t } = useTranslation('pages');
const { mode } = useTheme();
const { pluginEnabled } = usePlugins();
const { getMembersOfPoolFromNode } = usePoolMembers();
const { selectedActivePool, isOwner, isBouncer } = useActivePools();
const { selectedActivePool, isOwner, isBouncer, selectedPoolMemberCount } =
useActivePools();
const { colors } = useApi().network;

const listTitle = `${t('pools.poolMember', {
count: memberCount,
count: selectedPoolMemberCount,
})}`;
const annuncementBorderColor = colors.secondary[mode];

Expand Down Expand Up @@ -82,7 +83,7 @@ export const Members = ({ memberCount }: { memberCount: number }) => {
{pluginEnabled('subscan') ? (
<FetchPageMemberList
{...membersListProps}
memberCount={memberCount}
memberCount={selectedPoolMemberCount}
/>
) : (
<DefaultMemberList
Expand Down
6 changes: 3 additions & 3 deletions src/pages/Pools/Home/PoolStats/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import { StatsHead } from 'library/StatsHead';
import { Announcements } from './Announcements';
import { Wrapper } from './Wrappers';

export const PoolStats = ({ memberCount }: { memberCount: number }) => {
export const PoolStats = () => {
const { t } = useTranslation('pages');
const { network } = useApi();
const { selectedActivePool } = useActivePools();
const { selectedActivePool, selectedPoolMemberCount } = useActivePools();
const { getCurrentCommission } = usePoolCommission();

const { state, points } = selectedActivePool?.bondedPool || {};
Expand Down Expand Up @@ -58,7 +58,7 @@ export const PoolStats = ({ memberCount }: { memberCount: number }) => {
items.push(
{
label: t('pools.poolMembers'),
value: `${memberCount}`,
value: `${selectedPoolMemberCount}`,
},
{
label: t('pools.totalBonded'),
Expand Down
50 changes: 6 additions & 44 deletions src/pages/Pools/Home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@
// SPDX-License-Identifier: GPL-3.0-only

import { PageRow, PageTitle, RowSection } from '@polkadot-cloud/react';
import { useEffect, useRef, useState } from 'react';
import { useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import type { PageTitleTabProps } from '@polkadot-cloud/react/base/types';
import { useConnect } from 'contexts/Connect';
import { usePlugins } from 'contexts/Plugins';
import { useActivePools } from 'contexts/Pools/ActivePools';
import { useBondedPools } from 'contexts/Pools/BondedPools';
import { usePoolMembers } from 'contexts/Pools/PoolMembers';
import { usePoolMemberships } from 'contexts/Pools/PoolMemberships';
import { useSubscan } from 'contexts/Subscan';
import { CardWrapper } from 'library/Card/Wrappers';
import { PoolList } from 'library/PoolList/Default';
import { StatBoxList } from 'library/StatBoxList';
Expand All @@ -32,47 +28,19 @@ import { PoolsTabsProvider, usePoolsTabs } from './context';

export const HomeInner = () => {
const { t } = useTranslation('pages');
const { pluginEnabled } = usePlugins();
const { openModal } = useOverlay().modal;
const { activeAccount } = useConnect();
const {
favorites,
stats: { counterForBondedPools },
} = usePoolsConfig();
const { fetchPoolDetails } = useSubscan();
const { membership } = usePoolMemberships();
const { activeTab, setActiveTab } = usePoolsTabs();
const { bondedPools, getAccountPools } = useBondedPools();
const { getPoolRoles, selectedActivePool } = useActivePools();
const { getMembersOfPoolFromNode, poolMembersNode } = usePoolMembers();
const { getPoolRoles, selectedActivePool, selectedPoolMemberCount } =
useActivePools();
const accountPools = getAccountPools(activeAccount);
const totalAccountPools = Object.entries(accountPools).length;

const fetchingMemberCount = useRef<boolean>(false);

const getMemberCount = async () => {
if (!selectedActivePool?.id) {
setMemberCount(0);
return;
}
// If `Subscan` plugin is enabled, fetch member count directly from the API.
if (pluginEnabled('subscan') && !fetchingMemberCount.current) {
fetchingMemberCount.current = true;
const poolDetails = await fetchPoolDetails(selectedActivePool.id);
fetchingMemberCount.current = false;
setMemberCount(poolDetails?.member_count || 0);
return;
}
// If no plugin available, fetch all pool members from RPC and filter them to determine current
// pool member count. NOTE: Expensive operation.
setMemberCount(
getMembersOfPoolFromNode(selectedActivePool?.id ?? 0).length
);
};

// Store the pool member count.
const [memberCount, setMemberCount] = useState<number>(0);

let tabs: PageTitleTabProps[] = [
{
title: t('pools.overview'),
Expand All @@ -86,7 +54,7 @@ export const HomeInner = () => {
title: t('pools.members'),
active: activeTab === 1,
onClick: () => setActiveTab(1),
badge: String(memberCount),
badge: String(selectedPoolMemberCount),
});
}

Expand All @@ -112,12 +80,6 @@ export const HomeInner = () => {
}
}, [selectedActivePool]);

// Fetch pool member count. We use `membership` as a dependency as the member count could change
// in the UI when active account's membership changes.
useEffect(() => {
getMemberCount();
}, [activeAccount, selectedActivePool, membership, poolMembersNode]);

const ROW_HEIGHT = 220;

return (
Expand Down Expand Up @@ -170,13 +132,13 @@ export const HomeInner = () => {
</CardWrapper>
</PageRow>
<PageRow>
<PoolStats memberCount={memberCount} />
<PoolStats />
</PageRow>
</>
)}
</>
)}
{activeTab === 1 && <Members memberCount={memberCount} />}
{activeTab === 1 && <Members />}
{activeTab === 2 && (
<>
<PageRow>
Expand Down
18 changes: 9 additions & 9 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1453,17 +1453,17 @@
resolved "https://registry.npmjs.org/@polkadot-cloud/community/-/community-0.1.11.tgz#62f57c92d663f758bdee2b1a2147b74dd3de4971"
integrity sha512-R2ncl5idtiRfzA0a/Lo1j7HHo/4ztatz7xbnP9TPDMYk1JWCtoy77APnFLLukIUbGQGxw1kDVCP8U4X9KrZMKQ==

"@polkadot-cloud/core@^0.1.19":
version "0.1.19"
resolved "https://registry.npmjs.org/@polkadot-cloud/core/-/core-0.1.19.tgz#08b630fa15676cbd51bd0eb56ad5ca067fa200e7"
integrity sha512-UwbbyW2jVJm0aAKEOA2ybhTrw471u6+N/0KWdnHCi6IbuftnLQNoY9FYEWWub7K9FvzUR/vd+p+o/Pq06DMI4Q==
"@polkadot-cloud/core@^0.1.20":
version "0.1.20"
resolved "https://registry.npmjs.org/@polkadot-cloud/core/-/core-0.1.20.tgz#4bbad4295f37b0fd824f6a7f8823c667d0fbd3fb"
integrity sha512-GmaXMQK/GzeRkg6/MuDeCPltb0hQSdxz566acAy+OI1gMhvb0geBQ8Tbkt4iEbXusCYBnNyt3vxoqL/1doCpPw==

"@polkadot-cloud/react@^0.1.37":
version "0.1.37"
resolved "https://registry.npmjs.org/@polkadot-cloud/react/-/react-0.1.37.tgz#51402a792f6ed511be29aff9d925c34dcbca26e0"
integrity sha512-l/Gy/YLik+e98rNdUn1+jHSYAOLWu9IHA6MdyzulI8lyVpnejnHD3UWYKfbGZSUXGnp8LxR4ZrRLT8rHWwyNOg==
"@polkadot-cloud/react@^0.1.39":
version "0.1.39"
resolved "https://registry.npmjs.org/@polkadot-cloud/react/-/react-0.1.39.tgz#484cd7fc24a40df8e6189a7034b1f69f5afab38a"
integrity sha512-rZv0lMl3ec3YNXADu01qM1OgQ8ZLMl1XETewN33wB3ZYPWTCC2ylveF5daNMEU2UmfM03EaAr+A563Wb4ZsZ6Q==
dependencies:
"@polkadot-cloud/core" "^0.1.19"
"@polkadot-cloud/core" "^0.1.20"
"@polkadot-cloud/utils" "^0.0.11"
react-error-boundary "^4.0.11"

Expand Down

0 comments on commit 200f0cd

Please sign in to comment.