Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/webapp-yield' into webapp-dev
Browse files Browse the repository at this point in the history
  • Loading branch information
saltict committed Oct 21, 2023
2 parents c9f6316 + e222d25 commit ad74e94
Show file tree
Hide file tree
Showing 7 changed files with 288 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ const Component: React.FC<Props> = ({ className, transaction }: Props) => {
className={CN(className, 'alert-area')}
description={t("You are transferring {{symbol}} from {{network}} since you don't have enough DOT on the destination network.", { replace: { symbol: tokenInfo.symbol, network: chainInfo.name } })}
title={t('Pay attention!')}
type='warning'
type='info'
/>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ enum FilterValue {
POLKADOT_PARACHAIN = 'Polkadot parachain',
KUSAMA_PARACHAIN = 'Kusama parachain',
WON = 'won',
FAIL = 'failed',
IN_AUCTION = 'in auction'
}

Expand All @@ -50,8 +49,7 @@ function Component ({ className = '' }: Props): React.ReactElement<Props> {
const filterOptions = useMemo(() => [
{ label: t('Polkadot parachain'), value: FilterValue.POLKADOT_PARACHAIN },
{ label: t('Kusama parachain'), value: FilterValue.KUSAMA_PARACHAIN },
{ label: t('Won'), value: FilterValue.WON },
{ label: t('Fail'), value: FilterValue.FAIL }
{ label: t('Won'), value: FilterValue.WON }
], [t]);

const filterFunction = useMemo<(item: _CrowdloanItemType) => boolean>(() => {
Expand Down
2 changes: 1 addition & 1 deletion packages/extension-koni-ui/src/Popup/MissionPool/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const Component: React.FC<Props> = ({ className }: Props) => {
const { missions } = useSelector((state: RootState) => state.missionPool);

useEffect(() => {
if (location.pathname === '/mission-pools') {
if (location.pathname === '/home/mission-pools') {
setTitle(t('Mission Pools'));
}
}, [location.pathname, setTitle, t]);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
// Copyright 2019-2022 @subwallet/extension-koni-ui authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { useGetBalance, useSelector } from '@subwallet/extension-koni-ui/hooks';
import useTranslation from '@subwallet/extension-koni-ui/hooks/common/useTranslation';
import { Theme, ThemeProps } from '@subwallet/extension-koni-ui/types';
import { ActivityIndicator, Number, Typography } from '@subwallet/react-ui';
import CN from 'classnames';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import styled, { useTheme } from 'styled-components';

interface BalanceInfo {
token: string;
chain: string;
}

type Props = ThemeProps & {
address: string;
tokens: BalanceInfo[];
label?: string;
onBalanceReady?: (rs: boolean) => void;
}

interface PartProps {
token: string;
chain: string;
address: string;
setLoading: (val: boolean) => void;
setError: (val: string | null) => void;
showNetwork: boolean;
first: boolean;
showContent: boolean;
}

const parseToLoadingMap = (tokens: BalanceInfo[]): Record<string, boolean> => {
const result: Record<string, boolean> = {};

tokens.forEach(({ token }) => {
result[token] = true;
});

return result;
};

const parseToErrorMap = (tokens: BalanceInfo[]): Record<string, string | null> => {
const result: Record<string, string | null> = {};

tokens.forEach(({ token }) => {
result[token] = null;
});

return result;
};

const PartComponent: React.FC<PartProps> = (props: PartProps) => {
const { address, chain, first, setError, setLoading, showContent, showNetwork, token } = props;

const { token: theme } = useTheme() as Theme;
const { t } = useTranslation();

const { chainInfoMap } = useSelector((state) => state.chainStore);

const { error, isLoading, nativeTokenBalance, nativeTokenSlug, tokenBalance } = useGetBalance(chain, address, token, true);

const balance = useMemo(() => {
if (token) {
if (nativeTokenSlug === token) {
return nativeTokenBalance;
} else {
return tokenBalance;
}
}

return undefined;
}, [nativeTokenBalance, nativeTokenSlug, token, tokenBalance]);

const suffix = useMemo(() => {
let result = balance?.symbol || '';

const chainInfo = chainInfoMap[chain];

if (showNetwork && chainInfo) {
result += ` (${chainInfo.name})`;
}

return result;
}, [balance?.symbol, chain, chainInfoMap, showNetwork]);

useEffect(() => {
setLoading(isLoading);
}, [isLoading, setLoading]);

useEffect(() => {
setError(error);
}, [error, setError]);

if (isLoading || !showContent) {
return null;
}

return (
<>
{
!first && (
<span className={'__name'}>&nbsp;{t('and')}&nbsp;</span>
)
}
{
balance && (
<Number
decimal={balance.decimals || 18}
decimalColor={theme.colorTextTertiary}
intColor={theme.colorTextTertiary}
size={14}
suffix={suffix}
unitColor={theme.colorTextTertiary}
value={balance.value}
/>
)
}
</>
);
};

const Component = (props: Props) => {
const { address, className, label, onBalanceReady, tokens } = props;

const { t } = useTranslation();

const loadingRef = useRef<Record<string, boolean>>(parseToLoadingMap(tokens));
const errorRef = useRef<Record<string, string | null>>(parseToErrorMap(tokens));

const showNetwork = useMemo(() => {
let temp = '';

for (const { chain } of tokens) {
if (temp) {
if (temp !== chain) {
return true;
}
} else {
temp = chain;
}
}

return false;
}, [tokens]);

const [isLoading, _setIsLoading] = useState(true);
const [error, _setError] = useState<string | null>(null);

const setLoading = useCallback((slug: string) => {
return (data: boolean) => {
loadingRef.current[slug] = data;

let isLoading = false;

for (const loading of Object.values(loadingRef.current)) {
if (loading) {
isLoading = true;
break;
}
}

_setIsLoading(isLoading);
};
}, []);

const setError = useCallback((slug: string) => {
return (data: string | null) => {
errorRef.current[slug] = data;

let error: string | null = null;

for (const value of Object.values(errorRef.current)) {
if (value) {
error = value;
break;
}
}

_setError(error);
};
}, []);

useEffect(() => {
onBalanceReady?.(!isLoading && !error);
}, [error, isLoading, onBalanceReady]);

if (!address && !tokens.length) {
return <></>;
}

return (
<Typography.Paragraph className={CN(className, 'free-balance')}>
{!error && <span className='__label'>{label || t('Sender available balance:')}</span>}
{isLoading && <ActivityIndicator size={14} />}
{error && <Typography.Text className={'error-message'}>{error}</Typography.Text>}
{
tokens.map(({ chain, token }, index) => {
return (
<PartComponent
address={address}
chain={chain}
first={index === 0}
key={token}
setError={setError(token)}
setLoading={setLoading(token)}
showContent={!error && !isLoading}
showNetwork={showNetwork}
token={token}
/>
);
})
}
</Typography.Paragraph>
);
};

const FreeBalanceToYield = styled(Component)<Props>(({ theme: { token } }: Props) => {
return {
display: 'flex',
flexWrap: 'wrap',
color: token.colorTextTertiary,

'.__label': {
marginRight: 3
},

'.error-message': {
color: token.colorError
},

'&.ant-typography': {
marginBottom: 0
}
};
});

export default FreeBalanceToYield;
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
export { default as BondedBalance } from './BondedBalance';
export { default as FreeBalance } from './FreeBalance';
export { default as FreeBalanceToStake } from './FreeBalanceToStake';
export { default as FreeBalanceToYield } from './FreeBalanceToYield';
export { default as TransactionContent } from './TransactionContent';
export { default as TransactionFooter } from './TransactionFooter';
export { default as YieldOutlet } from './YieldOutlet';
Loading

0 comments on commit ad74e94

Please sign in to comment.