Display tip warning on no recipient balance (#6393)

This commit is contained in:
Jaco 2021-10-24 15:15:00 +02:00 committed by GitHub
parent 720f13844c
commit 8770390a58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 16 deletions

View File

@ -2,7 +2,8 @@
// SPDX-License-Identifier: Apache-2.0
import type BN from 'bn.js';
import type { AccountId, Balance, BlockNumber, OpenTip, OpenTipTo225 } from '@polkadot/types/interfaces';
import type { AccountId, Balance, BlockNumber, OpenTipTo225 } from '@polkadot/types/interfaces';
import type { PalletTipsOpenTip } from '@polkadot/types/lookup';
import React, { useEffect, useMemo, useState } from 'react';
import styled from 'styled-components';
@ -25,7 +26,7 @@ interface Props {
members: string[];
onSelect: (hash: string, isSelected: boolean, value: BN) => void;
onlyUntipped: boolean;
tip: OpenTip | OpenTipTo225;
tip: PalletTipsOpenTip | OpenTipTo225;
}
interface TipState {
@ -38,11 +39,11 @@ interface TipState {
median: BN;
}
function isCurrentTip (tip: OpenTip | OpenTipTo225): tip is OpenTip {
return !!(tip as OpenTip)?.findersFee;
function isCurrentTip (tip: PalletTipsOpenTip | OpenTipTo225): tip is PalletTipsOpenTip {
return !!(tip as PalletTipsOpenTip)?.findersFee;
}
function extractTipState (tip: OpenTip | OpenTipTo225, allAccounts: string[]): TipState {
function extractTipState (tip: PalletTipsOpenTip | OpenTipTo225, allAccounts: string[]): TipState {
const closesAt = tip.closes.unwrapOr(null);
let finder: AccountId | null = null;
let deposit: Balance | null = null;
@ -106,6 +107,7 @@ function Tip ({ bestNumber, className = '', defaultId, hash, isMember, members,
}
const { reason, tips, who } = tip;
const recipient = who.toString();
return (
<tr className={className}>
@ -166,6 +168,7 @@ function Tip ({ bestNumber, className = '', defaultId, hash, isMember, members,
isTipped={isTipped}
median={median}
members={members}
recipient={recipient}
/>
)
: (

View File

@ -2,11 +2,12 @@
// SPDX-License-Identifier: Apache-2.0
import type BN from 'bn.js';
import type { DeriveBalancesAll } from '@polkadot/api-derive/types';
import React, { useState } from 'react';
import { Button, InputAddress, InputBalance, Modal, TxButton } from '@polkadot/react-components';
import { useApi, useToggle } from '@polkadot/react-hooks';
import { Button, InputAddress, InputBalance, MarkWarning, Modal, TxButton } from '@polkadot/react-components';
import { useApi, useCall, useToggle } from '@polkadot/react-hooks';
import { useTranslation } from '../translate';
@ -17,14 +18,23 @@ interface Props {
isTipped: boolean;
median: BN;
members: string[];
recipient: string;
}
function TipEndorse ({ defaultId, hash, isMember, isTipped, median, members }: Props): React.ReactElement<Props> {
const transformBalance = {
transform: ({ freeBalance, reservedBalance }: DeriveBalancesAll): BN =>
freeBalance.add(reservedBalance)
};
function TipEndorse ({ defaultId, hash, isMember, isTipped, median, members, recipient }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const [isOpen, toggleOpen] = useToggle();
const [accountId, setAccountId] = useState<string | null>(defaultId);
const [value, setValue] = useState<BN | undefined>();
const totalBalance = useCall<BN>(api.derive.balances?.all, [recipient], transformBalance);
const tipTx = (api.tx.tips || api.tx.treasury).tip;
return (
<>
@ -41,7 +51,7 @@ function TipEndorse ({ defaultId, hash, isMember, isTipped, median, members }: P
isDisabled={!isMember || !isTipped}
isIcon
params={[hash, median]}
tx={(api.tx.tips || api.tx.treasury).tip}
tx={tipTx}
withoutLink
/>
{isOpen && (
@ -70,6 +80,9 @@ function TipEndorse ({ defaultId, hash, isMember, isTipped, median, members }: P
label={t<string>('value')}
onChange={setValue}
/>
{totalBalance && totalBalance.isZero() && (
<MarkWarning content={t<string>('The recipient account has no balance, ensure the tip is more than the existential deposit to create the account.')} />
)}
</Modal.Columns>
</Modal.Content>
<Modal.Actions>
@ -80,7 +93,7 @@ function TipEndorse ({ defaultId, hash, isMember, isTipped, median, members }: P
label={t<string>('Submit tip')}
onStart={toggleOpen}
params={[hash, value]}
tx={(api.tx.tips || api.tx.treasury).tip}
tx={tipTx}
/>
</Modal.Actions>
</Modal>

View File

@ -3,7 +3,8 @@
import type BN from 'bn.js';
import type { Option } from '@polkadot/types';
import type { OpenTip, OpenTipTo225 } from '@polkadot/types/interfaces';
import type { OpenTipTo225 } from '@polkadot/types/interfaces';
import type { PalletTipsOpenTip } from '@polkadot/types/lookup';
import React, { useMemo, useRef, useState } from 'react';
import styled from 'styled-components';
@ -23,11 +24,11 @@ interface Props {
onSelectTip: (hash: string, isSelected: boolean, value: BN) => void,
}
type Tip = [string, OpenTip | OpenTipTo225];
type Tip = [string, PalletTipsOpenTip | OpenTipTo225];
const TIP_OPTS = { withParams: true };
function extractTips (tipsWithHashes?: [[string[]], Option<OpenTip>[]], inHashes?: string[] | null): Tip[] | undefined {
function extractTips (tipsWithHashes?: [[string[]], Option<PalletTipsOpenTip>[]], inHashes?: string[] | null): Tip[] | undefined {
if (!tipsWithHashes || !inHashes) {
return undefined;
}
@ -35,8 +36,8 @@ function extractTips (tipsWithHashes?: [[string[]], Option<OpenTip>[]], inHashes
const [[hashes], optTips] = tipsWithHashes;
return optTips
.map((opt, index): [string, OpenTip | null] => [hashes[index], opt.unwrapOr(null)])
.filter((val): val is [string, OpenTip] => inHashes.includes(val[0]) && !!val[1])
.map((opt, index): [string, PalletTipsOpenTip | null] => [hashes[index], opt.unwrapOr(null)])
.filter((val): val is [string, PalletTipsOpenTip] => inHashes.includes(val[0]) && !!val[1])
.sort((a, b) =>
a[1].closes.isNone
? b[1].closes.isNone
@ -53,7 +54,7 @@ function Tips ({ className = '', defaultId, hashes, isMember, members, onSelectT
const { api } = useApi();
const [onlyUntipped, setOnlyUntipped] = useState(false);
const bestNumber = useBestNumber();
const tipsWithHashes = useCall<[[string[]], Option<OpenTip>[]]>(hashes && (api.query.tips || api.query.treasury).tips.multi, [hashes], TIP_OPTS);
const tipsWithHashes = useCall<[[string[]], Option<PalletTipsOpenTip>[]]>(hashes && (api.query.tips || api.query.treasury).tips.multi, [hashes], TIP_OPTS);
const tips = useMemo(
() => extractTips(tipsWithHashes, hashes),