Token selection dialog

This commit is contained in:
armaniferrante 2021-05-13 00:28:32 -07:00
parent 822797649c
commit 83e605fcc0
No known key found for this signature in database
GPG Key ID: 58BEF301E91F7828
4 changed files with 163 additions and 22 deletions

View File

@ -1,4 +1,5 @@
import React, { useState, useEffect } from "react";
import { Typography } from "@material-ui/core";
import { Provider } from "@project-serum/anchor";
// @ts-ignore
import Wallet from "@project-serum/sol-wallet-adapter";
@ -41,18 +42,25 @@ function App() {
}, [params]);
return (
<div>
{isConnected && (
<div
style={{
width: "450px",
marginTop: "64px",
marginLeft: "auto",
marginRight: "auto",
}}
>
<Swap provider={params.provider} tokenList={params.tokenList} />
</div>
<div
style={{
width: "450px",
marginLeft: "auto",
marginRight: "auto",
position: "absolute",
left: 0,
right: 0,
top: 0,
bottom: 0,
display: "flex",
justifyContent: "center",
flexDirection: "column",
}}
>
{isConnected ? (
<Swap provider={params.provider} tokenList={params.tokenList} />
) : (
<Typography style={{ textAlign: "center" }}>Disconnected</Typography>
)}
</div>
);

View File

@ -11,7 +11,12 @@ import { TokenListContainer, TokenInfo } from "@solana/spl-token-registry";
import { getOwnedTokenAccounts } from "../utils/tokens";
const SRM_MINT = new PublicKey("SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt");
const USDC_MINT = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
export const USDC_MINT = new PublicKey(
"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
);
export const USDT_MINT = new PublicKey(
"Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"
);
const SwapContext = React.createContext<null | SwapContext>(null);

View File

@ -1,5 +1,4 @@
import React, { useState, useContext } from "react";
import { BN } from "@project-serum/anchor";
import { useState } from "react";
import { PublicKey } from "@solana/web3.js";
import { TokenListContainer } from "@solana/spl-token-registry";
import { Provider } from "@project-serum/anchor";
@ -24,11 +23,13 @@ import {
useOwnedTokenAccount,
useMintAccount,
} from "./Context";
import TokenDialog from "./TokenDialog";
const useStyles = makeStyles((theme) => ({
const useStyles = makeStyles(() => ({
card: {
width: "450px",
borderRadius: "10px",
border: "solid 1pt #e0e0e0",
},
cardContent: {
marginLeft: "6px",
@ -229,6 +230,7 @@ function SwapTokenForm({
amount: number;
setAmount: (a: number) => void;
}) {
const [showTokenDialog, setShowTokenDialog] = useState(false);
const tokenAccount = useOwnedTokenAccount(mint);
const mintAccount = useMintAccount(mint);
@ -241,7 +243,7 @@ function SwapTokenForm({
justifyContent: "space-between",
}}
>
<TokenButton mint={mint} />
<TokenButton mint={mint} onClick={() => setShowTokenDialog(true)} />
<TextField
type="number"
value={amount}
@ -263,21 +265,32 @@ function SwapTokenForm({
: `-`}
</Typography>
</div>
<TokenDialog
setMint={setMint}
open={showTokenDialog}
onClose={() => setShowTokenDialog(false)}
/>
</Paper>
);
}
function TokenButton({ mint }: { mint: PublicKey }) {
function TokenButton({
mint,
onClick,
}: {
mint: PublicKey;
onClick: () => void;
}) {
return (
<Button style={{ width: "116px" }}>
<TokenIcon mint={mint} />
<Button onClick={onClick} style={{ width: "116px" }}>
<TokenIcon mint={mint} style={{ width: "25px" }} />
<TokenName mint={mint} />
<ExpandMore />
</Button>
);
}
function TokenIcon({ mint }: { mint: PublicKey }) {
export function TokenIcon({ mint, style }: { mint: PublicKey; style: any }) {
const tokenList = useTokenList();
let tokenInfo = tokenList.filter((t) => t.address === mint.toString())[0];
return (
@ -288,7 +301,11 @@ function TokenIcon({ mint }: { mint: PublicKey }) {
flexDirection: "column",
}}
>
<img style={{ width: "25px" }} src={tokenInfo.logoURI} />
{tokenInfo.logoURI ? (
<img alt="token logo" style={style} src={tokenInfo.logoURI} />
) : (
<div style={style}></div>
)}
</div>
);
}

View File

@ -0,0 +1,111 @@
import { useState } from "react";
import { PublicKey } from "@solana/web3.js";
import {
makeStyles,
Dialog,
DialogTitle,
DialogContent,
TextField,
List,
ListItem,
Typography,
} from "@material-ui/core";
import { useSwapContext, useTokenList, USDC_MINT, USDT_MINT } from "./Context";
import { TokenIcon } from "./Swap";
const useStyles = makeStyles((theme) => ({
dialogContent: {
paddingTop: 0,
},
textField: {
width: "100%",
border: "solid 1pt #ccc",
borderRadius: "10px",
marginBottom: "8px",
},
}));
export default function TokenDialog({
open,
onClose,
setMint,
}: {
open: boolean;
onClose: () => void;
setMint: (mint: PublicKey) => void;
}) {
const [tokenFilter, setTokenFilter] = useState("");
const styles = useStyles();
const { swapClient } = useSwapContext();
return (
<Dialog
open={open}
onClose={onClose}
PaperProps={{
style: {
borderRadius: "10px",
},
}}
>
<div style={{ width: "420px" }}>
<DialogTitle style={{ fontWeight: "bold" }}>Select a token</DialogTitle>
<DialogContent className={styles.dialogContent}>
<TextField
className={styles.textField}
placeholder={"Search name"}
value={tokenFilter}
onChange={(e) => setTokenFilter(e.target.value)}
InputProps={{
disableUnderline: true,
style: { padding: "10px" },
}}
/>
<div>
<List disablePadding>
{swapClient
.tokens()
.concat([USDC_MINT, USDT_MINT])
.map((mint) => (
<TokenListItem
mint={mint}
onClick={(mint) => {
setMint(mint);
onClose();
}}
/>
))}
</List>
</div>
</DialogContent>
</div>
</Dialog>
);
}
function TokenListItem({
mint,
onClick,
}: {
mint: PublicKey;
onClick: (mint: PublicKey) => void;
}) {
return (
<ListItem button onClick={() => onClick(mint)}>
<TokenIcon mint={mint} style={{ width: "30px", borderRadius: "15px" }} />
<TokenName mint={mint} />
</ListItem>
);
}
function TokenName({ mint }: { mint: PublicKey }) {
const tokenList = useTokenList();
let tokenInfo = tokenList.filter((t) => t.address === mint.toString())[0];
return (
<div style={{ marginLeft: "16px" }}>
<Typography style={{ fontWeight: "bold" }}>{tokenInfo.symbol}</Typography>
<Typography color="textSecondary" style={{ fontSize: "14px" }}>
{tokenInfo.name}
</Typography>
</div>
);
}