From f309743b2f10da47db6b3d91b8370e417b60af90 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Tue, 24 Mar 2020 08:27:15 +0100 Subject: [PATCH] Swap referendum pass/fail to Tag (#2448) --- packages/page-accounts/src/Account.tsx | 5 +- packages/page-address-book/src/Address.tsx | 5 +- .../src/Overview/Referendum.tsx | 10 ++-- .../src/Overview/useIsPassing.ts | 48 ++++++++----------- packages/react-components/src/Badge.tsx | 6 +-- packages/react-components/src/Row.tsx | 4 +- packages/react-components/src/Tag.tsx | 42 ++++++++++++++++ packages/react-components/src/index.tsx | 1 + 8 files changed, 75 insertions(+), 46 deletions(-) create mode 100644 packages/react-components/src/Tag.tsx diff --git a/packages/page-accounts/src/Account.tsx b/packages/page-accounts/src/Account.tsx index 86c9e650c5..c207948dda 100644 --- a/packages/page-accounts/src/Account.tsx +++ b/packages/page-accounts/src/Account.tsx @@ -7,9 +7,8 @@ import { ActionStatus } from '@polkadot/react-components/Status/types'; import { RecoveryConfig } from '@polkadot/types/interfaces'; import React, { useCallback, useState, useEffect } from 'react'; -import { Label } from 'semantic-ui-react'; import styled from 'styled-components'; -import { AddressInfo, AddressSmall, Badge, Button, ChainLock, Forget, Icon, IdentityIcon, InputTags, LinkExternal, Menu, Popup, Input } from '@polkadot/react-components'; +import { AddressInfo, AddressSmall, Badge, Button, ChainLock, Forget, Icon, IdentityIcon, Input, InputTags, LinkExternal, Menu, Popup, Tag } from '@polkadot/react-components'; import { useApi, useCall, useToggle } from '@polkadot/react-hooks'; import { Option } from '@polkadot/types'; import keyring from '@polkadot/ui-keyring'; @@ -309,7 +308,7 @@ function Account ({ address, className, filter, isFavorite, toggleFavorite }: Pr
{tags.length ? tags.map((tag): React.ReactNode => ( - + )) : } diff --git a/packages/page-address-book/src/Address.tsx b/packages/page-address-book/src/Address.tsx index fb1179952b..4356a9b723 100644 --- a/packages/page-address-book/src/Address.tsx +++ b/packages/page-address-book/src/Address.tsx @@ -7,9 +7,8 @@ import { KeyringAddress } from '@polkadot/ui-keyring/types'; import { ActionStatus } from '@polkadot/react-components/Status/types'; import React, { useEffect, useState } from 'react'; -import { Label } from 'semantic-ui-react'; import styled from 'styled-components'; -import { AddressSmall, AddressInfo, Button, ChainLock, Icon, InputTags, Input, LinkExternal, Forget, Menu, Popup } from '@polkadot/react-components'; +import { AddressSmall, AddressInfo, Button, ChainLock, Icon, InputTags, Input, LinkExternal, Forget, Menu, Popup, Tag } from '@polkadot/react-components'; import { useApi, useCall } from '@polkadot/react-hooks'; import keyring from '@polkadot/ui-keyring'; import Transfer from '@polkadot/app-accounts/modals/Transfer'; @@ -222,7 +221,7 @@ function Address ({ address, className, filter, isFavorite, toggleFavorite }: Pr
{tags.length ? tags.map((tag): React.ReactNode => ( - + )) : } diff --git a/packages/page-democracy/src/Overview/Referendum.tsx b/packages/page-democracy/src/Overview/Referendum.tsx index 6ccdda20b9..b2b2956ed4 100644 --- a/packages/page-democracy/src/Overview/Referendum.tsx +++ b/packages/page-democracy/src/Overview/Referendum.tsx @@ -7,7 +7,7 @@ import { BlockNumber } from '@polkadot/types/interfaces'; import React, { useMemo } from 'react'; import styled from 'styled-components'; -import { AddressMini, Badge, Button, Expander, Icon, LinkExternal } from '@polkadot/react-components'; +import { AddressMini, Button, Expander, LinkExternal, Tag } from '@polkadot/react-components'; import { useApi, useCall } from '@polkadot/react-hooks'; import { FormatBalance, BlockToTime } from '@polkadot/react-query'; import { formatNumber, isBoolean } from '@polkadot/util'; @@ -84,12 +84,10 @@ function Referendum ({ className, value }: Props): React.ReactElement | n {isBoolean(isPassing) && ( - } - isInline - isTooltip - type={isPassing ? 'green' : 'brown'} + label={isPassing ? t('passing') : t('failing')} /> )} diff --git a/packages/page-democracy/src/Overview/useIsPassing.ts b/packages/page-democracy/src/Overview/useIsPassing.ts index ce0097f821..9beae83a6b 100644 --- a/packages/page-democracy/src/Overview/useIsPassing.ts +++ b/packages/page-democracy/src/Overview/useIsPassing.ts @@ -46,17 +46,11 @@ function newtonIteration (n: BN, x0: BN): BN { return newtonIteration(n, x1); } -// https://golb.hplar.ch/2018/09/javascript-bigint.html -function sqrt (value: BN): BN { - if (value.ltn(0)) { - throw new Error('square root of negative numbers is not supported'); - } - - if (value.ltn(2)) { - return value; - } - - return newtonIteration(value, new BN(1)); +// TODO Replace with bnSqrt from @polkadot/util once that hits 2.7 +function bnSqrt (value: BN): BN { + return value.ltn(2) + ? value + : newtonIteration(value, new BN(1)); } export default function useIsPassing (referendum: DerivedReferendum): boolean | undefined { @@ -65,26 +59,22 @@ export default function useIsPassing (referendum: DerivedReferendum): boolean | const [isPassing, setIsPassing] = useState(undefined); useEffect((): void => { - try { - // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion - const { tally, threshold } = (referendum.status as ReferendumStatus); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + const { tally, threshold } = (referendum.status as ReferendumStatus); - if (totalIssuance && tally) { - const sqrtVoters = sqrt(tally.turnout); - const sqrtElectorate = sqrt(totalIssuance); + if (totalIssuance && tally) { + const sqrtVoters = bnSqrt(tally.turnout); + const sqrtElectorate = bnSqrt(totalIssuance); - setIsPassing( - sqrtVoters.isZero() - ? false - : threshold.isSimplemajority - ? tally.ayes.gt(tally.nays) - : threshold.isSupermajorityapproval - ? compareRationals(tally.nays, sqrtVoters, tally.ayes, sqrtElectorate) - : compareRationals(tally.nays, sqrtElectorate, tally.ayes, sqrtVoters) - ); - } - } catch (error) { - console.error(error); + setIsPassing( + sqrtVoters.isZero() + ? false + : threshold.isSimplemajority + ? tally.ayes.gt(tally.nays) + : threshold.isSupermajorityapproval + ? compareRationals(tally.nays, sqrtVoters, tally.ayes, sqrtElectorate) + : compareRationals(tally.nays, sqrtElectorate, tally.ayes, sqrtVoters) + ); } }, [referendum, totalIssuance]); diff --git a/packages/react-components/src/Badge.tsx b/packages/react-components/src/Badge.tsx index 92fcb05748..454f895d65 100644 --- a/packages/react-components/src/Badge.tsx +++ b/packages/react-components/src/Badge.tsx @@ -22,12 +22,12 @@ interface Props { let badgeId = 0; function Badge ({ className, hover, info, isGray, isInline, isSmall, isTooltip, onClick, type }: Props): React.ReactElement | null { - const [key] = useState(`${Date.now()}-${badgeId++}`); + const [trigger] = useState(`badge-hover-${Date.now()}-${badgeId++}`); return (
{hover && ( )} diff --git a/packages/react-components/src/Row.tsx b/packages/react-components/src/Row.tsx index 5ffc488f86..f60ea3e5a2 100644 --- a/packages/react-components/src/Row.tsx +++ b/packages/react-components/src/Row.tsx @@ -5,7 +5,6 @@ import { DeriveAccountInfo } from '@polkadot/api-derive/types'; import { KeyringItemType } from '@polkadot/ui-keyring/types'; -import { Label } from 'semantic-ui-react'; import React from 'react'; import Button from './Button'; @@ -13,6 +12,7 @@ import { classes, toShortAddress } from './util'; import CopyButton from './CopyButton'; import Input from './Input'; import InputTags from './InputTags'; +import Tag from './Tag'; export const styles = ` text-align: left; @@ -354,7 +354,7 @@ export default class Row

extends React.P !tags.length ? (isEditable ? add tags : undefined) : tags.map((tag): React.ReactNode => ( - + )) } {isEditable && this.renderEditIcon()} diff --git a/packages/react-components/src/Tag.tsx b/packages/react-components/src/Tag.tsx new file mode 100644 index 0000000000..4f901233f0 --- /dev/null +++ b/packages/react-components/src/Tag.tsx @@ -0,0 +1,42 @@ +// Copyright 2017-2020 @polkadot/react-components authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import React, { useState } from 'react'; +import { Label } from 'semantic-ui-react'; + +import Tooltip from './Tooltip'; + +interface Props { + className?: string; + color?: 'green' | 'grey' | 'red'; + hover?: React.ReactNode; + label: React.ReactNode; +} + +let tagId = 0; + +function Tag ({ className, color, hover, label }: Props): React.ReactElement { + const [trigger] = useState(`tag-hover-${Date.now()}-${tagId++}`); + + return ( + + ); +} + +export default React.memo(Tag); diff --git a/packages/react-components/src/index.tsx b/packages/react-components/src/index.tsx index b53bb32195..98b4581267 100644 --- a/packages/react-components/src/index.tsx +++ b/packages/react-components/src/index.tsx @@ -77,6 +77,7 @@ export { default as Status, StatusContext } from './Status'; export { default as SummaryBox } from './SummaryBox'; export { default as Table } from './Table'; export { default as Tabs } from './Tabs'; +export { default as Tag } from './Tag'; export { default as Toggle } from './Toggle'; export { default as Tooltip } from './Tooltip'; export { default as TxButton } from './TxButton';