Skip to content

Commit ebf6eef

Browse files
committed
Save token selection and amounts when going back
1 parent 3d7fd1e commit ebf6eef

File tree

2 files changed

+99
-95
lines changed

2 files changed

+99
-95
lines changed

packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SwapWidget.tsx

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
"use client";
22

3-
import { useCallback, useState } from "react";
3+
import { useCallback, useEffect, useState } from "react";
4+
import { getAddress } from "thirdweb/utils";
45
import type { Buy, Sell } from "../../../../../bridge/index.js";
56
import type { TokenWithPrices } from "../../../../../bridge/types/Token.js";
67
import type { ThirdwebClient } from "../../../../../client/client.js";
8+
import { NATIVE_TOKEN_ADDRESS } from "../../../../../constants/addresses.js";
79
import type { SupportedFiatCurrency } from "../../../../../pay/convert/type.js";
810
import { toTokens } from "../../../../../utils/units.js";
911
import { CustomThemeProvider } from "../../../../core/design-system/CustomThemeProvider.js";
@@ -22,8 +24,9 @@ import { SuccessScreen } from "../payment-success/SuccessScreen.js";
2224
import { QuoteLoader } from "../QuoteLoader.js";
2325
import { StepRunner } from "../StepRunner.js";
2426
import { useActiveWalletInfo } from "./hooks.js";
27+
import { getLastUsedTokens, setLastUsedTokens } from "./storage.js";
2528
import { SwapUI } from "./swap-ui.js";
26-
import type { SwapWidgetConnectOptions } from "./types.js";
29+
import type { SwapWidgetConnectOptions, TokenSelection } from "./types.js";
2730
import { useBridgeChains } from "./use-bridge-chains.js";
2831

2932
export type SwapWidgetProps = {
@@ -233,6 +236,72 @@ function SwapWidgetContent(props: SwapWidgetProps) {
233236
const [screen, setScreen] = useState<SwapWidgetScreen>({ id: "1:swap-ui" });
234237
const activeWalletInfo = useActiveWalletInfo();
235238

239+
const [amountSelection, setAmountSelection] = useState<{
240+
type: "buy" | "sell";
241+
amount: string;
242+
}>(() => {
243+
if (props.prefill?.buyToken?.amount) {
244+
return {
245+
type: "buy",
246+
amount: props.prefill.buyToken.amount,
247+
};
248+
}
249+
if (props.prefill?.sellToken?.amount) {
250+
return {
251+
type: "sell",
252+
amount: props.prefill.sellToken.amount,
253+
};
254+
}
255+
return {
256+
type: "buy",
257+
amount: "",
258+
};
259+
});
260+
261+
const [buyToken, setBuyToken] = useState<TokenSelection | undefined>(() => {
262+
if (props.prefill?.buyToken) {
263+
return {
264+
tokenAddress:
265+
props.prefill.buyToken.tokenAddress ||
266+
getAddress(NATIVE_TOKEN_ADDRESS),
267+
chainId: props.prefill.buyToken.chainId,
268+
};
269+
}
270+
const last = getLastUsedTokens()?.buyToken;
271+
if (last) {
272+
return {
273+
tokenAddress: getAddress(last.tokenAddress),
274+
chainId: last.chainId,
275+
};
276+
}
277+
return undefined;
278+
});
279+
const [sellToken, setSellToken] = useState<TokenSelection | undefined>(() => {
280+
if (props.prefill?.sellToken) {
281+
return {
282+
tokenAddress:
283+
props.prefill.sellToken.tokenAddress ||
284+
getAddress(NATIVE_TOKEN_ADDRESS),
285+
chainId: props.prefill.sellToken.chainId,
286+
};
287+
}
288+
const last = getLastUsedTokens()?.sellToken;
289+
if (last) {
290+
return {
291+
tokenAddress: getAddress(last.tokenAddress),
292+
chainId: last.chainId,
293+
};
294+
}
295+
return undefined;
296+
});
297+
298+
// persist selections to localStorage whenever they change
299+
useEffect(() => {
300+
if (buyToken) {
301+
setLastUsedTokens({ buyToken, sellToken });
302+
}
303+
}, [buyToken, sellToken]);
304+
236305
// preload requests
237306
useBridgeChains(props.client);
238307

@@ -262,7 +331,12 @@ function SwapWidgetContent(props: SwapWidgetProps) {
262331
connectOptions={props.connectOptions}
263332
currency={props.currency || "USD"}
264333
activeWalletInfo={activeWalletInfo}
265-
prefill={props.prefill}
334+
buyToken={buyToken}
335+
sellToken={sellToken}
336+
setBuyToken={setBuyToken}
337+
setSellToken={setSellToken}
338+
amountSelection={amountSelection}
339+
setAmountSelection={setAmountSelection}
266340
onSwap={(quote, selection) => {
267341
setScreen({
268342
quote,
@@ -382,6 +456,11 @@ function SwapWidgetContent(props: SwapWidgetProps) {
382456
completedStatuses={screen.completedStatuses}
383457
onDone={() => {
384458
setScreen({ id: "1:swap-ui" });
459+
// clear amounts
460+
setAmountSelection({
461+
type: "buy",
462+
amount: "",
463+
});
385464
}}
386465
preparedQuote={screen.preparedQuote}
387466
uiOptions={{

packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx

Lines changed: 17 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
DiscIcon,
66
} from "@radix-ui/react-icons";
77
import { useQuery } from "@tanstack/react-query";
8-
import { useEffect, useState } from "react";
8+
import { useState } from "react";
99
import { Buy, Sell } from "../../../../../bridge/index.js";
1010
import type { BridgeChain } from "../../../../../bridge/types/Chain.js";
1111
import type { TokenWithPrices } from "../../../../../bridge/types/Token.js";
@@ -42,7 +42,6 @@ import { Spacer } from "../../components/Spacer.js";
4242
import { Text } from "../../components/text.js";
4343
import { SelectBuyToken } from "./select-buy-token.js";
4444
import { SelectSellToken } from "./select-sell-token.js";
45-
import { getLastUsedTokens, setLastUsedTokens } from "./storage.js";
4645
import type {
4746
ActiveWalletInfo,
4847
SwapWidgetConnectOptions,
@@ -67,106 +66,32 @@ type SwapUIProps = {
6766
mode: "buy" | "sell";
6867
},
6968
) => void;
70-
prefill:
71-
| {
72-
buyToken?: {
73-
tokenAddress?: string;
74-
chainId: number;
75-
amount?: string;
76-
};
77-
sellToken?: {
78-
tokenAddress?: string;
79-
chainId: number;
80-
amount?: string;
81-
};
82-
}
83-
| undefined;
69+
buyToken: TokenSelection | undefined;
70+
sellToken: TokenSelection | undefined;
71+
setBuyToken: (token: TokenSelection | undefined) => void;
72+
setSellToken: (token: TokenSelection | undefined) => void;
73+
amountSelection: {
74+
type: "buy" | "sell";
75+
amount: string;
76+
};
77+
setAmountSelection: (amountSelection: {
78+
type: "buy" | "sell";
79+
amount: string;
80+
}) => void;
8481
};
8582

8683
export function SwapUI(props: SwapUIProps) {
8784
const [screen, setScreen] = useState<
8885
"base" | "select-buy-token" | "select-sell-ui"
8986
>("base");
9087

91-
const [amountSelection, setAmountSelection] = useState<{
92-
type: "buy" | "sell";
93-
amount: string;
94-
}>(() => {
95-
if (props.prefill?.buyToken?.amount) {
96-
return {
97-
type: "buy",
98-
amount: props.prefill.buyToken.amount,
99-
};
100-
}
101-
if (props.prefill?.sellToken?.amount) {
102-
return {
103-
type: "sell",
104-
amount: props.prefill.sellToken.amount,
105-
};
106-
}
107-
return {
108-
type: "buy",
109-
amount: "",
110-
};
111-
});
112-
113-
const [buyToken, setBuyToken] = useState<TokenSelection | undefined>(() => {
114-
if (props.prefill?.buyToken) {
115-
return {
116-
tokenAddress:
117-
props.prefill.buyToken.tokenAddress ||
118-
getAddress(NATIVE_TOKEN_ADDRESS),
119-
chainId: props.prefill.buyToken.chainId,
120-
};
121-
}
122-
const last = getLastUsedTokens()?.buyToken;
123-
if (last) {
124-
return {
125-
tokenAddress: getAddress(last.tokenAddress),
126-
chainId: last.chainId,
127-
};
128-
}
129-
return undefined;
130-
});
131-
const [sellToken, setSellToken] = useState<TokenSelection | undefined>(() => {
132-
if (props.prefill?.sellToken) {
133-
return {
134-
tokenAddress:
135-
props.prefill.sellToken.tokenAddress ||
136-
getAddress(NATIVE_TOKEN_ADDRESS),
137-
chainId: props.prefill.sellToken.chainId,
138-
};
139-
}
140-
const last = getLastUsedTokens()?.sellToken;
141-
if (last) {
142-
return {
143-
tokenAddress: getAddress(last.tokenAddress),
144-
chainId: last.chainId,
145-
};
146-
}
147-
return undefined;
148-
});
149-
150-
// persist selections to localStorage whenever they change
151-
useEffect(() => {
152-
if (buyToken) {
153-
setLastUsedTokens({ buyToken, sellToken });
154-
}
155-
}, [buyToken, sellToken]);
156-
15788
if (screen === "base") {
15889
return (
15990
<SwapUIBase
16091
{...props}
16192
onSelectToken={(type) => {
16293
setScreen(type === "buy" ? "select-buy-token" : "select-sell-ui");
16394
}}
164-
buyToken={buyToken}
165-
sellToken={sellToken}
166-
setBuyToken={setBuyToken}
167-
setSellToken={setSellToken}
168-
amountSelection={amountSelection}
169-
setAmountSelection={setAmountSelection}
17095
/>
17196
);
17297
}
@@ -176,9 +101,9 @@ export function SwapUI(props: SwapUIProps) {
176101
<SelectBuyToken
177102
onBack={() => setScreen("base")}
178103
client={props.client}
179-
selectedToken={buyToken}
104+
selectedToken={props.buyToken}
180105
setSelectedToken={(token) => {
181-
setBuyToken(token);
106+
props.setBuyToken(token);
182107
setScreen("base");
183108
}}
184109
/>
@@ -190,10 +115,10 @@ export function SwapUI(props: SwapUIProps) {
190115
<SelectSellToken
191116
onBack={() => setScreen("base")}
192117
client={props.client}
193-
selectedToken={sellToken}
118+
selectedToken={props.sellToken}
194119
theme={props.theme}
195120
setSelectedToken={(token) => {
196-
setSellToken(token);
121+
props.setSellToken(token);
197122
setScreen("base");
198123
}}
199124
activeWalletInfo={props.activeWalletInfo}

0 commit comments

Comments
 (0)