From ccfb98bdaef9e190da95b52f226514e95bb33b69 Mon Sep 17 00:00:00 2001 From: Gala Date: Thu, 15 Dec 2022 14:18:01 +0100 Subject: [PATCH 01/10] bond table changes --- .../src/components/Bonding/BondedMixnode.tsx | 70 +++++++++++++------ nym-wallet/src/components/IdentityKey.tsx | 18 ++--- .../general-settings/ParametersSettings.tsx | 34 +++------ nym-wallet/src/utils/index.ts | 2 + nym-wallet/src/utils/nextEpoch.ts | 23 ++++++ 5 files changed, 92 insertions(+), 55 deletions(-) create mode 100644 nym-wallet/src/utils/nextEpoch.ts diff --git a/nym-wallet/src/components/Bonding/BondedMixnode.tsx b/nym-wallet/src/components/Bonding/BondedMixnode.tsx index 6ff0151b29..69b37b64f5 100644 --- a/nym-wallet/src/components/Bonding/BondedMixnode.tsx +++ b/nym-wallet/src/components/Bonding/BondedMixnode.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { Box, Button, Chip, Stack, Tooltip, Typography } from '@mui/material'; import { Link } from '@nymproject/react/link/Link'; @@ -11,6 +11,9 @@ import { Node as NodeIcon } from '../../svg-icons/node'; import { Cell, Header, NodeTable } from './NodeTable'; import { BondedMixnodeActions, TBondedMixnodeActions } from './BondedMixnodeActions'; import { NodeStats } from './NodeStats'; +import { getIntervalAsDate } from 'src/utils'; + +const textWhenNotName = 'This node has not yet set a name'; const headers: Header[] = [ { @@ -63,6 +66,7 @@ export const BondedMixnode = ({ network?: Network; onActionSelect: (action: TBondedMixnodeActions) => void; }) => { + const [nextEpoch, setNextEpoch] = useState(); const navigate = useNavigate(); const { name, @@ -78,6 +82,15 @@ export const BondedMixnode = ({ identityKey, host, } = mixnode; + + const getNextInterval = async () => { + try { + const { nextEpoch } = await getIntervalAsDate(); + setNextEpoch(nextEpoch); + } catch { + setNextEpoch(Error()); + } + }; const cells: Cell[] = [ { cell: `${stake.amount} ${stake.denom}`, @@ -121,6 +134,10 @@ export const BondedMixnode = ({ }, ]; + useEffect(() => { + getNextInterval(); + }, []); + return ( - {name && ( - - - {name} - - + {name?.includes(textWhenNotName) ? null : ( + + {name} + )} - + } Action={ - isMixnode(mixnode) && ( - - - - - - ) + + {isMixnode(mixnode) && ( + + + + + + )} + {nextEpoch instanceof Error ? null : ( + + Next epoch starts at {nextEpoch} + + )} + } > diff --git a/nym-wallet/src/components/IdentityKey.tsx b/nym-wallet/src/components/IdentityKey.tsx index bca08ab68c..372a6bf40d 100644 --- a/nym-wallet/src/components/IdentityKey.tsx +++ b/nym-wallet/src/components/IdentityKey.tsx @@ -1,13 +1,15 @@ import React from 'react'; -import { Stack, Typography } from '@mui/material'; +import { Stack, Typography, Tooltip } from '@mui/material'; import { CopyToClipboard } from '@nymproject/react/clipboard/CopyToClipboard'; import { splice } from 'src/utils'; -export const IdentityKey = ({ identityKey }: { identityKey: string }) => ( - - - {splice(6, identityKey)} - - - +export const IdentityKey = ({ identityKey, tooltipTitle }: { identityKey: string; tooltipTitle?: string }) => ( + + + + {splice(6, identityKey)} + + + + ); diff --git a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx index 7aa7407a48..ba98640ddb 100644 --- a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx +++ b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx @@ -15,10 +15,8 @@ import { import { useTheme } from '@mui/material/styles'; import { CurrencyDenom, MixNodeCostParams } from '@nymproject/types'; import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField'; -import { add, format, fromUnixTime } from 'date-fns'; import { isMixnode } from 'src/types'; import { - getCurrentInterval, getPendingIntervalEvents, simulateUpdateMixnodeCostParams, simulateVestingUpdateMixnodeCostParams, @@ -29,6 +27,7 @@ import { TBondedMixnode } from 'src/context/bonding'; import { SimpleModal } from 'src/components/Modals/SimpleModal'; import { bondedNodeParametersValidationSchema } from 'src/components/Bonding/forms/mixnodeValidationSchema'; import { Console } from 'src/utils/console'; +import { getIntervalAsDate } from 'src/utils'; import { Alert } from 'src/components/Alert'; import { ChangeMixCostParams } from 'src/pages/bonding/types'; import { AppContext } from 'src/context'; @@ -63,27 +62,14 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode defaultValues, }); - const getIntervalAsDate = async () => { - const interval = await getCurrentInterval(); - const secondsToNextInterval = - Number(interval.epochs_in_interval - interval.current_epoch_id) * Number(interval.epoch_length_seconds); - - setIntervalTime( - format( - add(new Date(), { - seconds: secondsToNextInterval, - }), - 'MM/dd/yyyy HH:mm', - ), - ); - setNextEpoch( - format( - add(fromUnixTime(Number(interval.current_epoch_start_unix)), { - seconds: Number(interval.epoch_length_seconds), - }), - 'HH:mm', - ), - ); + const getNextInterval = async () => { + try { + const { intervalTime, nextEpoch } = await getIntervalAsDate(); + setNextEpoch(nextEpoch); + setIntervalTime(intervalTime); + } catch { + console.log('cant retrieve next interval'); + } }; const getPendingEvents = async () => { @@ -107,7 +93,7 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode }; useEffect(() => { - getIntervalAsDate(); + getNextInterval(); getPendingEvents(); }, []); diff --git a/nym-wallet/src/utils/index.ts b/nym-wallet/src/utils/index.ts index 49d56c6f72..7e8cdca1f5 100644 --- a/nym-wallet/src/utils/index.ts +++ b/nym-wallet/src/utils/index.ts @@ -7,6 +7,8 @@ import { TPoolOption } from 'src/components'; import { getDefaultMixnodeCostParams, getLockedCoins, getSpendableCoins, userBalance } from '../requests'; import { Console } from './console'; +export * from './nextEpoch'; + export const validateKey = (key: string, bytesLength: number): boolean => { // it must be a valid base58 key try { diff --git a/nym-wallet/src/utils/nextEpoch.ts b/nym-wallet/src/utils/nextEpoch.ts new file mode 100644 index 0000000000..799cf635fd --- /dev/null +++ b/nym-wallet/src/utils/nextEpoch.ts @@ -0,0 +1,23 @@ +import { getCurrentInterval } from 'src/requests'; +import { add, format, fromUnixTime } from 'date-fns'; + +export const getIntervalAsDate = async () => { + const interval = await getCurrentInterval(); + const secondsToNextInterval = + Number(interval.epochs_in_interval - interval.current_epoch_id) * Number(interval.epoch_length_seconds); + + const intervalTime = format( + add(new Date(), { + seconds: secondsToNextInterval, + }), + 'MM/dd/yyyy HH:mm', + ); + const nextEpoch = format( + add(fromUnixTime(Number(interval.current_epoch_start_unix)), { + seconds: Number(interval.epoch_length_seconds), + }), + 'HH:mm', + ); + + return { intervalTime, nextEpoch }; +}; \ No newline at end of file From 9af6f824d447835a868382fca371118e86f6c7f1 Mon Sep 17 00:00:00 2001 From: Gala Date: Thu, 15 Dec 2022 15:22:44 +0100 Subject: [PATCH 02/10] removing epoch on settings and fixing divider position --- .../general-settings/ParametersSettings.tsx | 20 +++++++++++-------- nym-wallet/src/utils/nextEpoch.ts | 2 +- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx index ba98640ddb..4315ba0d94 100644 --- a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx +++ b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx @@ -38,7 +38,6 @@ import { LoadingModal } from 'src/components/Modals/LoadingModal'; export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode }): JSX.Element => { const [openConfirmationModal, setOpenConfirmationModal] = useState(false); const [intervalTime, setIntervalTime] = useState(); - const [nextEpoch, setNextEpoch] = useState(); const [pendingUpdates, setPendingUpdates] = useState(); const { clientDetails } = useContext(AppContext); const theme = useTheme(); @@ -65,7 +64,6 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode const getNextInterval = async () => { try { const { intervalTime, nextEpoch } = await getIntervalAsDate(); - setNextEpoch(nextEpoch); setIntervalTime(intervalTime); } catch { console.log('cant retrieve next interval'); @@ -123,7 +121,16 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode }; return ( - + {fee && ( - - {`Next epoch ${nextEpoch}`} - {`Next interval: ${intervalTime}`} } @@ -192,7 +196,7 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode )} - + @@ -235,7 +239,7 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode - + + + {!!delegations?.length && ( + + )} + + + + + {nextEpoch instanceof Error ? null : ( + + Next epoch starts at {nextEpoch} + + )} + )} {delegationsComponent(delegations)} From 6c6e5d98b7d7630e5f7b8db57239a48aef0ea97f Mon Sep 17 00:00:00 2001 From: Gala Date: Fri, 16 Dec 2022 08:04:33 +0100 Subject: [PATCH 06/10] delegations layout and tooltip when delegate with vesting --- .../components/Delegation/DelegationItem.tsx | 20 +++--- nym-wallet/src/pages/delegation/index.tsx | 69 ++++++++++--------- 2 files changed, 48 insertions(+), 41 deletions(-) diff --git a/nym-wallet/src/components/Delegation/DelegationItem.tsx b/nym-wallet/src/components/Delegation/DelegationItem.tsx index d800f9f487..8a3df8dc17 100644 --- a/nym-wallet/src/components/Delegation/DelegationItem.tsx +++ b/nym-wallet/src/components/Delegation/DelegationItem.tsx @@ -28,16 +28,20 @@ export const DelegationItem = ({ onItemActionClick?: (item: DelegationWithEverything, action: DelegationListItemActions) => void; }) => { const operatingCost = isDelegation(item) && item.cost_params?.interval_operating_cost; + const usesVestingContractTokens = item.uses_vesting_contract_tokens; + + const tooltipText = () => { + if (nodeIsUnbonded) { + return 'This node has unbonded and it does not exist anymore. You need to undelegate from it to get your stake and outstanding rewards (if any) back.'; + } else if (usesVestingContractTokens) { + return 'Delegation made with locked tockens'; + } else { + return ''; + } + }; return ( - + {nodeIsUnbonded ? ( diff --git a/nym-wallet/src/pages/delegation/index.tsx b/nym-wallet/src/pages/delegation/index.tsx index 5f581dd967..8fb399c6a8 100644 --- a/nym-wallet/src/pages/delegation/index.tsx +++ b/nym-wallet/src/pages/delegation/index.tsx @@ -343,42 +343,45 @@ export const Delegation: FC<{ isStorybook?: boolean }> = ({ isStorybook }) => { <> - - Delegations - + + {' '} + + + Delegations + + {!!delegations?.length && ( + + )} + + {!!delegations?.length && ( + + )} + {!!delegations?.length && ( - - {!!delegations?.length && ( - - )} - - - - - {nextEpoch instanceof Error ? null : ( - - Next epoch starts at {nextEpoch} - - )} - + + {nextEpoch instanceof Error ? null : ( + + Next epoch starts at {nextEpoch} + + )} )} {delegationsComponent(delegations)} From 8ed312fe1c3cc889d4e08b2cc250a67bc8eadb70 Mon Sep 17 00:00:00 2001 From: Gala Date: Mon, 19 Dec 2022 10:37:04 +0100 Subject: [PATCH 07/10] refactor --- nym-wallet/src/components/Delegation/DelegationItem.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nym-wallet/src/components/Delegation/DelegationItem.tsx b/nym-wallet/src/components/Delegation/DelegationItem.tsx index 8a3df8dc17..1b4327621c 100644 --- a/nym-wallet/src/components/Delegation/DelegationItem.tsx +++ b/nym-wallet/src/components/Delegation/DelegationItem.tsx @@ -28,12 +28,11 @@ export const DelegationItem = ({ onItemActionClick?: (item: DelegationWithEverything, action: DelegationListItemActions) => void; }) => { const operatingCost = isDelegation(item) && item.cost_params?.interval_operating_cost; - const usesVestingContractTokens = item.uses_vesting_contract_tokens; const tooltipText = () => { if (nodeIsUnbonded) { return 'This node has unbonded and it does not exist anymore. You need to undelegate from it to get your stake and outstanding rewards (if any) back.'; - } else if (usesVestingContractTokens) { + } else if (item.uses_vesting_contract_tokens) { return 'Delegation made with locked tockens'; } else { return ''; From 094b2db7f7fccc6caa0f99c462d88fc86a2b5c64 Mon Sep 17 00:00:00 2001 From: Gala Date: Mon, 19 Dec 2022 10:52:29 +0100 Subject: [PATCH 08/10] refactor --- nym-wallet/src/components/Bonding/BondedMixnode.tsx | 2 +- nym-wallet/src/pages/delegation/index.tsx | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/nym-wallet/src/components/Bonding/BondedMixnode.tsx b/nym-wallet/src/components/Bonding/BondedMixnode.tsx index 69b37b64f5..92b4bdb965 100644 --- a/nym-wallet/src/components/Bonding/BondedMixnode.tsx +++ b/nym-wallet/src/components/Bonding/BondedMixnode.tsx @@ -66,7 +66,7 @@ export const BondedMixnode = ({ network?: Network; onActionSelect: (action: TBondedMixnodeActions) => void; }) => { - const [nextEpoch, setNextEpoch] = useState(); + const [nextEpoch, setNextEpoch] = useState(); const navigate = useNavigate(); const { name, diff --git a/nym-wallet/src/pages/delegation/index.tsx b/nym-wallet/src/pages/delegation/index.tsx index 8fb399c6a8..50ac86b354 100644 --- a/nym-wallet/src/pages/delegation/index.tsx +++ b/nym-wallet/src/pages/delegation/index.tsx @@ -36,10 +36,9 @@ export const Delegation: FC<{ isStorybook?: boolean }> = ({ isStorybook }) => { const [confirmationModalProps, setConfirmationModalProps] = useState(); const [currentDelegationListActionItem, setCurrentDelegationListActionItem] = useState(); const [saturationError, setSaturationError] = useState<{ action: 'compound' | 'delegate'; saturation: string }>(); - const [nextEpoch, setNextEpoch] = useState(); + const [nextEpoch, setNextEpoch] = useState(); const theme = useTheme(); - const { clientDetails, network, From 2b2b04f147e19bc99daa8bac0bad8e12fce9c502 Mon Sep 17 00:00:00 2001 From: Gala Date: Mon, 19 Dec 2022 15:23:39 +0100 Subject: [PATCH 09/10] refactor from PR request --- .../src/components/Bonding/BondedMixnode.tsx | 6 +++++- nym-wallet/src/components/IdentityKey.tsx | 16 +++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/nym-wallet/src/components/Bonding/BondedMixnode.tsx b/nym-wallet/src/components/Bonding/BondedMixnode.tsx index 92b4bdb965..ae32fdefba 100644 --- a/nym-wallet/src/components/Bonding/BondedMixnode.tsx +++ b/nym-wallet/src/components/Bonding/BondedMixnode.tsx @@ -155,7 +155,11 @@ export const BondedMixnode = ({ {name} )} - + + + + + } Action={ diff --git a/nym-wallet/src/components/IdentityKey.tsx b/nym-wallet/src/components/IdentityKey.tsx index 372a6bf40d..acf4019ce7 100644 --- a/nym-wallet/src/components/IdentityKey.tsx +++ b/nym-wallet/src/components/IdentityKey.tsx @@ -3,13 +3,11 @@ import { Stack, Typography, Tooltip } from '@mui/material'; import { CopyToClipboard } from '@nymproject/react/clipboard/CopyToClipboard'; import { splice } from 'src/utils'; -export const IdentityKey = ({ identityKey, tooltipTitle }: { identityKey: string; tooltipTitle?: string }) => ( - - - - {splice(6, identityKey)} - - - - +export const IdentityKey = ({ identityKey }: { identityKey: string }) => ( + + + {splice(6, identityKey)} + + + ); From 07edf1a626e89c52656e27c383505488bff9c6c5 Mon Sep 17 00:00:00 2001 From: Gala Date: Mon, 19 Dec 2022 15:27:35 +0100 Subject: [PATCH 10/10] cleaning --- nym-wallet/src/components/IdentityKey.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nym-wallet/src/components/IdentityKey.tsx b/nym-wallet/src/components/IdentityKey.tsx index acf4019ce7..bca08ab68c 100644 --- a/nym-wallet/src/components/IdentityKey.tsx +++ b/nym-wallet/src/components/IdentityKey.tsx @@ -1,10 +1,10 @@ import React from 'react'; -import { Stack, Typography, Tooltip } from '@mui/material'; +import { Stack, Typography } from '@mui/material'; import { CopyToClipboard } from '@nymproject/react/clipboard/CopyToClipboard'; import { splice } from 'src/utils'; export const IdentityKey = ({ identityKey }: { identityKey: string }) => ( - + {splice(6, identityKey)}