Skip to content

Commit

Permalink
support show pending token (#183)
Browse files Browse the repository at this point in the history
* support show pending token

* pump version
  • Loading branch information
zhfnjust authored Dec 28, 2023
1 parent 86f6e45 commit 3a434a9
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 39 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added src/assets/checkbox-checked.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/checkbox-unchecked.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions src/components/Reusable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ export const HeaderText = styled.h1<ColorThemeProps>`
text-align: center;
`;


export const SubHeaderText = styled.h1<ColorThemeProps>`
font-size: 1rem;
color: ${({ theme }) => theme.white};
font-family: Arial, Helvetica, sans-serif;
font-weight: 400;
margin: 0.1rem 0;
text-align: center;
`;


export const Divider = styled.hr`
width: 80%;
opacity: 0.3;
Expand Down
6 changes: 4 additions & 2 deletions src/hooks/useOrds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export const useOrds = () => {
const ordList = await getOrdUtxos(ordAddress);
setOrdinals({
initialized: true,
data: ordList,
data: ordList.filter(o => o.satoshis === 1),
});

const bsv20List: Array<BSV20> = await getBsv20Balances(ordAddress);
Expand All @@ -147,9 +147,11 @@ export const useOrds = () => {
// If other information is needed later, call `cacheTokenInfos` to obtain more Tokens information.
// await cacheTokenInfos(bsv20List.map((bsv20) => bsv20.id));


const data = bsv20List.filter((o) => ((o.all.confirmed + o.all.pending) > 0n) && typeof o.dec === 'number')
setBSV20s({
initialized: true,
data: bsv20List.filter((o) => o.all.confirmed > 0n),
data: data,
});
} catch (error) {
console.error('getOrdinals failed:', error);
Expand Down
143 changes: 108 additions & 35 deletions src/pages/OrdWallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
FormContainer,
HeaderText,
ReceiveContent,
SubHeaderText,
Text,
} from '../components/Reusable';
import { Show } from '../components/Show';
Expand All @@ -30,7 +31,9 @@ import { BSV_DECIMAL_CONVERSION } from '../utils/constants';
import { isBSV20v2, normalize, showAmount } from '../utils/ordi';
import { sleep } from '../utils/sleep';
import { BSV20Id } from '../components/BSV20Id';

import checkboxChecked from '../assets/checkbox-checked.png';
import checkboxunChecked from '../assets/checkbox-unchecked.png';
import { IconButton } from '../components/IconButton';
const OrdinalsList = styled.div`
display: flex;
align-items: center;
Expand Down Expand Up @@ -66,6 +69,10 @@ const OneSatLogo = styled.img`
margin: 0 0 1rem 0;
`;

export const CheckBox = styled.div`
margin: 0.5rem 0.5rem;
`;

const Icon = styled.img<{ size?: string }>`
width: ${(props) => props.size ?? '1.5rem'};
height: ${(props) => props.size ?? '1.5rem'};
Expand All @@ -88,6 +95,12 @@ export const OrdButtonContainer = styled(ButtonContainer)`
margin: 0.5rem 0 0.5rem 0;
`;

export const BSV20Header = styled.div`
display: flex;
align-items: center;
justify-content: center;
`;

const TokenIcon = styled.img`
width: 2.5rem;
height: 2.5rem;
Expand Down Expand Up @@ -115,6 +128,12 @@ const BSV20Container = styled.div`

type PageState = 'main' | 'receive' | 'transfer' | 'list' | 'cancel' | 'sendBSV20';


interface Token {
isConfirmed: boolean,
info: BSV20,
}

export const OrdWallet = () => {
const { theme } = useTheme();
const { setSelected } = useBottomMenu();
Expand Down Expand Up @@ -142,7 +161,9 @@ export const OrdWallet = () => {
const { addSnackbar, message } = useSnackbar();
const { isPasswordRequired } = useWeb3Context();

const [token, setToken] = useState<BSV20 | null>(null);
const [token, setToken] = useState<Token | null>(null);
const [showConfirmed, setShowConfirmed] = useState(true);
const [showPending, setShowPending] = useState(true);
const [tokenSendAmount, setTokenSendAmount] = useState<bigint | null>(null);

useEffect(() => {
Expand Down Expand Up @@ -307,7 +328,7 @@ export const OrdWallet = () => {
return;
}

const sendBSV20Res = await sendBSV20(token.id, receiveAddress, BigInt(tokenSendAmount), passwordConfirm);
const sendBSV20Res = await sendBSV20(token.info.id, receiveAddress, BigInt(tokenSendAmount), passwordConfirm);

if (!sendBSV20Res.txid || sendBSV20Res.error) {
const message = getErrorMessage(sendBSV20Res);
Expand All @@ -326,14 +347,15 @@ export const OrdWallet = () => {
});
};

const userSelectedAmount = (inputValue: string, token: BSV20) => {
const amtStr = normalize(inputValue, token.dec);
const userSelectedAmount = (inputValue: string, token: Token) => {
const amtStr = normalize(inputValue, token.info.dec);

const amt = BigInt(amtStr);
setTokenSendAmount(amt);
if (amt > token.all.confirmed) {
const total = token.isConfirmed ? token.info.all.confirmed : token.info.all.pending;
if (amt > total) {
setTimeout(() => {
setTokenSendAmount(token.all.confirmed);
setTokenSendAmount(total);
}, 500);
}
};
Expand Down Expand Up @@ -388,26 +410,77 @@ export const OrdWallet = () => {
}
>
<BSV20List>
{bsv20s.data.map((b) => {
return (
<BSV20Item
theme={theme}
id={b.id}
name={getTokenName(b)}
amount={showAmount(b.all.confirmed, b.dec)}
key={b.id}
iconUrl={b.icon ? `${getOrdinalsBaseUrl()}/content/${b.icon}` : null}
selected={false}
onClick={async () => {
setToken(b);
setPageState('sendBSV20');
}}
onCopyTokenId={() => {
addSnackbar('Copied', 'info', 1000);
}}
/>
);
})}
<BSV20Header>
<SubHeaderText theme={theme}>{bsv20s.data.filter(d => d.all.confirmed > 0n).length} Confirmed tokens
</SubHeaderText>
<CheckBox>
<IconButton icon={showConfirmed ? checkboxChecked : checkboxunChecked} onClick={()=>{
setShowConfirmed(!showConfirmed)
}}/>
</CheckBox>
</BSV20Header>
<Divider></Divider>

<Show when={showConfirmed}>
{bsv20s.data.filter(d => d.all.confirmed > 0n).map((b) => {
return (
<BSV20Item
theme={theme}
id={b.id}
name={getTokenName(b)}
amount={showAmount(b.all.confirmed, b.dec)}
key={b.id}
iconUrl={b.icon ? `${getOrdinalsBaseUrl()}/content/${b.icon}` : null}
selected={false}
onClick={async () => {
setToken({
isConfirmed: true,
info: b
});
setPageState('sendBSV20');
}}
onCopyTokenId={() => {
addSnackbar('Copied', 'info', 1000);
}}
/>
);
})}
</Show>

<Show when={bsv20s.data.filter(d => d.all.pending > 0n).length > 0}>
<BSV20Header>
<SubHeaderText theme={theme}>{bsv20s.data.filter(d => d.all.pending > 0n).length} Pending tokens
</SubHeaderText>
<CheckBox>
<IconButton icon={showPending ? checkboxChecked : checkboxunChecked} onClick={()=>{
setShowPending(!showPending)
}}/>
</CheckBox>
</BSV20Header>

<Divider></Divider>
<Show when={showPending}>
{bsv20s.data.filter(d => d.all.pending > 0n).map((b) => {
return (
<BSV20Item
theme={theme}
id={b.id}
name={getTokenName(b)}
amount={showAmount(b.all.pending, b.dec)}
key={b.id}
iconUrl={b.icon ? `${getOrdinalsBaseUrl()}/content/${b.icon}` : null}
selected={false}
onClick={async () => {
addSnackbar('Pending tokens cannot be sent!', 'error', 1000);
}}
onCopyTokenId={() => {
addSnackbar('Copied', 'info', 1000);
}}
/>
);
})}
</Show>
</Show>
</BSV20List>
</Show>
<OrdButtonContainer>
Expand Down Expand Up @@ -606,24 +679,24 @@ export const OrdWallet = () => {
/>
{token ? (
<ConfirmContent>
<TransferBSV20Header theme={theme}>Send {getTokenName(token)}</TransferBSV20Header>
<TransferBSV20Header theme={theme}>Send {getTokenName(token.info)}</TransferBSV20Header>
<BSV20Container>
<Balance
theme={theme}
style={{ cursor: 'pointer' }}
onClick={() => userSelectedAmount(String(Number(token.all.confirmed)), token)}
>{`Available Balance: ${showAmount(token.all.confirmed, token.dec)}`}</Balance>
onClick={() => userSelectedAmount(String(Number(token.info.all.confirmed)), token)}
>{`Available Balance: ${showAmount(token.info.all.confirmed, token.info.dec)}`}</Balance>

<Show when={!!token.icon && token.icon.length > 0}>
<TokenIcon src={`${getOrdinalsBaseUrl()}/content/${token.icon}`} />
<Show when={!!token.info.icon && token.info.icon.length > 0}>
<TokenIcon src={`${getOrdinalsBaseUrl()}/content/${token.info.icon}`} />
</Show>
</BSV20Container>

<Show when={isBSV20v2(token.id)}>
<Show when={isBSV20v2(token.info.id)}>
<BSV20Container>
<BSV20Id
theme={theme}
id={token.id}
id={token.info.id}
onCopyTokenId={() => {
addSnackbar('Copied', 'info', 1000);
}}
Expand All @@ -647,7 +720,7 @@ export const OrdWallet = () => {
placeholder="Enter Token Amount"
type="number"
step={'1'}
value={tokenSendAmount !== null ? showAmount(tokenSendAmount, token.dec) : ''}
value={tokenSendAmount !== null ? showAmount(tokenSendAmount, token.info.dec) : ''}
onChange={(e) => {
const inputValue = e.target.value;

Expand Down

0 comments on commit 3a434a9

Please sign in to comment.