Token selection dialog
This commit is contained in:
parent
822797649c
commit
83e605fcc0
16
src/App.tsx
16
src/App.tsx
|
@ -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",
|
||||
position: "absolute",
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
{isConnected ? (
|
||||
<Swap provider={params.provider} tokenList={params.tokenList} />
|
||||
</div>
|
||||
) : (
|
||||
<Typography style={{ textAlign: "center" }}>Disconnected</Typography>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue