@hot-labs/kit 1.2.0-alpha.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -9
- package/build/HotConnector.d.ts +8 -7
- package/build/HotConnector.js +21 -24
- package/build/HotConnector.js.map +1 -1
- package/build/OmniConnector.d.ts +5 -0
- package/build/OmniConnector.js +5 -5
- package/build/OmniConnector.js.map +1 -1
- package/build/OmniWallet.d.ts +10 -17
- package/build/OmniWallet.js +14 -19
- package/build/OmniWallet.js.map +1 -1
- package/build/core/Intents.d.ts +53 -43
- package/build/core/Intents.js +207 -133
- package/build/core/Intents.js.map +1 -1
- package/build/core/api.d.ts +30 -2
- package/build/core/api.js +43 -10
- package/build/core/api.js.map +1 -1
- package/build/core/bridge.js +1 -1
- package/build/core/bridge.js.map +1 -1
- package/build/core/index.d.ts +1 -1
- package/build/core/index.js +1 -1
- package/build/core/index.js.map +1 -1
- package/build/core/telemetry.d.ts +13 -0
- package/build/core/telemetry.js +27 -0
- package/build/core/telemetry.js.map +1 -0
- package/build/core/token.d.ts +1 -0
- package/build/core/token.js +3 -0
- package/build/core/token.js.map +1 -1
- package/build/core/tokens.js +0 -8
- package/build/core/tokens.js.map +1 -1
- package/build/core/types.d.ts +17 -0
- package/build/core/utils.d.ts +1 -0
- package/build/core/utils.js +21 -1
- package/build/core/utils.js.map +1 -1
- package/build/cosmos/connector.d.ts +2 -2
- package/build/cosmos/connector.js +17 -21
- package/build/cosmos/connector.js.map +1 -1
- package/build/cosmos/wallet.d.ts +2 -4
- package/build/cosmos/wallet.js +3 -8
- package/build/cosmos/wallet.js.map +1 -1
- package/build/evm/connector.d.ts +1 -0
- package/build/evm/connector.js +4 -0
- package/build/evm/connector.js.map +1 -1
- package/build/evm/wallet.d.ts +2 -1
- package/build/evm/wallet.js +7 -5
- package/build/evm/wallet.js.map +1 -1
- package/build/exchange.d.ts +4 -1
- package/build/exchange.js +24 -30
- package/build/exchange.js.map +1 -1
- package/build/hot-wallet/google.js +10 -5
- package/build/hot-wallet/google.js.map +1 -1
- package/build/hot-wallet/proxy.js +2 -2
- package/build/hot-wallet/proxy.js.map +1 -1
- package/build/index.d.ts +2 -1
- package/build/index.js +2 -1
- package/build/index.js.map +1 -1
- package/build/near/connector.js +2 -2
- package/build/near/connector.js.map +1 -1
- package/build/{core/nearRpc.d.ts → near/rpc.d.ts} +0 -1
- package/build/{core/nearRpc.js → near/rpc.js} +8 -22
- package/build/near/rpc.js.map +1 -0
- package/build/near/wallet.d.ts +4 -4
- package/build/near/wallet.js +36 -30
- package/build/near/wallet.js.map +1 -1
- package/build/solana/{protocol.d.ts → WalletStandard.d.ts} +1 -1
- package/build/solana/{protocol.js → WalletStandard.js} +1 -1
- package/build/solana/WalletStandard.js.map +1 -0
- package/build/solana/connector.d.ts +1 -1
- package/build/solana/connector.js +9 -8
- package/build/solana/connector.js.map +1 -1
- package/build/solana/injected/solana-wallet.js.map +1 -1
- package/build/solana/wallet.d.ts +5 -7
- package/build/solana/wallet.js +8 -17
- package/build/solana/wallet.js.map +1 -1
- package/build/solana/{wallets.js → walletStandartList.js} +1 -1
- package/build/solana/walletStandartList.js.map +1 -0
- package/build/stellar/connector.d.ts +0 -2
- package/build/stellar/connector.js +1 -4
- package/build/stellar/connector.js.map +1 -1
- package/build/stellar/wallet.d.ts +10 -8
- package/build/stellar/wallet.js +12 -16
- package/build/stellar/wallet.js.map +1 -1
- package/build/ton/connector.d.ts +0 -1
- package/build/ton/connector.js +1 -4
- package/build/ton/connector.js.map +1 -1
- package/build/ton/wallet.d.ts +2 -3
- package/build/ton/wallet.js +3 -4
- package/build/ton/wallet.js.map +1 -1
- package/build/tron/connector.d.ts +51 -0
- package/build/tron/connector.js +65 -0
- package/build/tron/connector.js.map +1 -0
- package/build/tron/index.d.ts +6 -0
- package/build/tron/index.js +5 -0
- package/build/tron/index.js.map +1 -0
- package/build/tron/wallet.d.ts +52 -0
- package/build/tron/wallet.js +122 -0
- package/build/tron/wallet.js.map +1 -0
- package/build/ui/Popup.d.ts +2 -2
- package/build/ui/Popup.js +5 -1
- package/build/ui/Popup.js.map +1 -1
- package/build/ui/bridge/Bridge.js +389 -0
- package/build/ui/bridge/Bridge.js.map +1 -0
- package/build/ui/{payment → bridge}/SelectRecipient.js +3 -3
- package/build/ui/bridge/SelectRecipient.js.map +1 -0
- package/build/ui/{payment → bridge}/SelectSender.js +2 -2
- package/build/ui/bridge/SelectSender.js.map +1 -0
- package/build/ui/{payment → bridge}/SelectToken.js +4 -3
- package/build/ui/bridge/SelectToken.js.map +1 -0
- package/build/ui/{payment → bridge}/TokenCard.d.ts +7 -9
- package/build/ui/bridge/TokenCard.js +65 -0
- package/build/ui/bridge/TokenCard.js.map +1 -0
- package/build/ui/connect/AuthPopup.js +1 -1
- package/build/ui/connect/AuthPopup.js.map +1 -1
- package/build/ui/connect/ConnectWallet.d.ts +7 -2
- package/build/ui/connect/ConnectWallet.js +7 -7
- package/build/ui/connect/ConnectWallet.js.map +1 -1
- package/build/ui/connect/PrimaryWallet.d.ts +6 -0
- package/build/ui/connect/PrimaryWallet.js +18 -0
- package/build/ui/connect/PrimaryWallet.js.map +1 -0
- package/build/ui/connect/WCRequest.js +1 -1
- package/build/ui/connect/WCRequest.js.map +1 -1
- package/build/ui/connect/WalletPicker.js +1 -1
- package/build/ui/connect/WalletPicker.js.map +1 -1
- package/build/ui/icons/arrow-right.d.ts +3 -1
- package/build/ui/icons/arrow-right.js +3 -3
- package/build/ui/icons/arrow-right.js.map +1 -1
- package/build/ui/icons/close.js +1 -1
- package/build/ui/icons/close.js.map +1 -1
- package/build/ui/icons/exchange.d.ts +3 -4
- package/build/ui/icons/exchange.js +2 -2
- package/build/ui/icons/exchange.js.map +1 -1
- package/build/ui/icons/logout.js +1 -1
- package/build/ui/icons/logout.js.map +1 -1
- package/build/ui/icons/pending.js +1 -1
- package/build/ui/icons/pending.js.map +1 -1
- package/build/ui/icons/plus.d.ts +2 -0
- package/build/ui/icons/plus.js +6 -0
- package/build/ui/icons/plus.js.map +1 -0
- package/build/ui/icons/qr.js +1 -1
- package/build/ui/icons/qr.js.map +1 -1
- package/build/ui/icons/refresh.d.ts +2 -0
- package/build/ui/icons/refresh.js +6 -0
- package/build/ui/icons/refresh.js.map +1 -0
- package/build/ui/icons/search.js +1 -1
- package/build/ui/icons/search.js.map +1 -1
- package/build/ui/icons/switch.js +1 -1
- package/build/ui/icons/switch.js.map +1 -1
- package/build/ui/icons/wallet.js +1 -1
- package/build/ui/icons/wallet.js.map +1 -1
- package/build/ui/{payment → profile}/DepositQR.js.map +1 -1
- package/build/ui/profile/Payment.d.ts +23 -0
- package/build/ui/profile/Payment.js +150 -0
- package/build/ui/profile/Payment.js.map +1 -0
- package/build/ui/profile/Profile.d.ts +7 -0
- package/build/ui/profile/Profile.js +135 -0
- package/build/ui/profile/Profile.js.map +1 -0
- package/build/ui/router.d.ts +19 -5
- package/build/ui/router.js +21 -9
- package/build/ui/router.js.map +1 -1
- package/build/ui/styles.js +4 -11
- package/build/ui/styles.js.map +1 -1
- package/build/ui/uikit/Stepper.d.ts +13 -0
- package/build/ui/uikit/Stepper.js +22 -0
- package/build/ui/uikit/Stepper.js.map +1 -0
- package/build/ui/uikit/Toast.d.ts +4 -0
- package/build/ui/uikit/Toast.js +33 -0
- package/build/ui/uikit/Toast.js.map +1 -0
- package/build/ui/uikit/button.d.ts +2 -0
- package/build/ui/uikit/button.js +52 -0
- package/build/ui/uikit/button.js.map +1 -0
- package/build/ui/uikit/image.d.ts +6 -0
- package/build/ui/uikit/image.js +38 -0
- package/build/ui/uikit/image.js.map +1 -0
- package/build/ui/uikit/loader.d.ts +2 -0
- package/build/ui/uikit/loader.js +50 -0
- package/build/ui/uikit/loader.js.map +1 -0
- package/build/ui/uikit/tabs.d.ts +12 -0
- package/build/ui/uikit/tabs.js +35 -0
- package/build/ui/uikit/tabs.js.map +1 -0
- package/build/ui/uikit/text.d.ts +6 -0
- package/build/ui/uikit/text.js +59 -0
- package/build/ui/uikit/text.js.map +1 -0
- package/build/ui/utils.d.ts +1 -0
- package/build/ui/utils.js +20 -0
- package/build/ui/utils.js.map +1 -0
- package/package.json +8 -4
- package/src/HotConnector.ts +24 -31
- package/src/OmniConnector.ts +10 -9
- package/src/OmniWallet.ts +24 -25
- package/src/core/Intents.ts +222 -151
- package/src/core/api.ts +56 -10
- package/src/core/bridge.ts +3 -2
- package/src/core/index.ts +1 -1
- package/src/core/telemetry.ts +28 -0
- package/src/core/token.ts +4 -0
- package/src/core/tokens.ts +0 -9
- package/src/core/types.ts +21 -0
- package/src/core/utils.ts +17 -1
- package/src/cosmos/connector.ts +22 -26
- package/src/cosmos/wallet.ts +3 -8
- package/src/evm/connector.ts +5 -0
- package/src/evm/wallet.ts +9 -6
- package/src/exchange.ts +24 -30
- package/src/hot-wallet/google.ts +12 -5
- package/src/hot-wallet/proxy.ts +2 -2
- package/src/index.ts +3 -1
- package/src/near/connector.ts +2 -2
- package/src/{core/nearRpc.ts → near/rpc.ts} +9 -23
- package/src/near/wallet.ts +39 -31
- package/src/solana/{protocol.ts → WalletStandard.ts} +2 -4
- package/src/solana/connector.ts +9 -8
- package/src/solana/injected/solana-wallet.ts +6 -6
- package/src/solana/wallet.ts +11 -20
- package/src/stellar/connector.ts +1 -6
- package/src/stellar/wallet.ts +17 -17
- package/src/ton/connector.ts +1 -5
- package/src/ton/wallet.ts +3 -3
- package/src/tron/connector.ts +89 -0
- package/src/tron/index.ts +7 -0
- package/src/tron/wallet.ts +146 -0
- package/src/ui/Popup.tsx +12 -4
- package/src/ui/{payment → bridge}/Bridge.tsx +266 -212
- package/src/ui/{payment → bridge}/SelectRecipient.tsx +5 -4
- package/src/ui/{payment → bridge}/SelectSender.tsx +5 -5
- package/src/ui/{payment → bridge}/SelectToken.tsx +6 -4
- package/src/ui/bridge/TokenCard.tsx +99 -0
- package/src/ui/connect/AuthPopup.tsx +1 -1
- package/src/ui/connect/ConnectWallet.tsx +16 -10
- package/src/ui/connect/PrimaryWallet.tsx +65 -0
- package/src/ui/connect/WCRequest.tsx +1 -1
- package/src/ui/connect/WalletPicker.tsx +1 -1
- package/src/ui/icons/arrow-right.tsx +3 -4
- package/src/ui/icons/close.tsx +1 -1
- package/src/ui/icons/exchange.tsx +4 -11
- package/src/ui/icons/logout.tsx +4 -13
- package/src/ui/icons/pending.tsx +2 -4
- package/src/ui/icons/plus.tsx +12 -0
- package/src/ui/icons/qr.tsx +1 -2
- package/src/ui/icons/refresh.tsx +20 -0
- package/src/ui/icons/search.tsx +4 -4
- package/src/ui/icons/switch.tsx +4 -4
- package/src/ui/icons/wallet.tsx +2 -4
- package/src/ui/profile/Payment.tsx +309 -0
- package/src/ui/{payment → profile}/Profile.tsx +110 -70
- package/src/ui/router.tsx +57 -17
- package/src/ui/styles.ts +4 -11
- package/src/ui/uikit/Stepper.tsx +50 -0
- package/src/ui/uikit/Toast.tsx +45 -0
- package/src/ui/uikit/button.tsx +53 -0
- package/src/ui/uikit/image.tsx +45 -0
- package/src/ui/uikit/loader.tsx +52 -0
- package/src/ui/uikit/tabs.tsx +56 -0
- package/src/ui/uikit/text.tsx +64 -0
- package/src/ui/utils.ts +14 -0
- package/build/core/nearRpc.js.map +0 -1
- package/build/solana/protocol.js.map +0 -1
- package/build/solana/wallets.js.map +0 -1
- package/build/ui/payment/Bridge.js +0 -358
- package/build/ui/payment/Bridge.js.map +0 -1
- package/build/ui/payment/Payment.d.ts +0 -16
- package/build/ui/payment/Payment.js +0 -50
- package/build/ui/payment/Payment.js.map +0 -1
- package/build/ui/payment/Profile.d.ts +0 -8
- package/build/ui/payment/Profile.js +0 -110
- package/build/ui/payment/Profile.js.map +0 -1
- package/build/ui/payment/SelectRecipient.js.map +0 -1
- package/build/ui/payment/SelectSender.js.map +0 -1
- package/build/ui/payment/SelectToken.js.map +0 -1
- package/build/ui/payment/TokenCard.js +0 -63
- package/build/ui/payment/TokenCard.js.map +0 -1
- package/src/ui/payment/Payment.tsx +0 -79
- package/src/ui/payment/TokenCard.tsx +0 -98
- package/build/solana/{wallets.d.ts → walletStandartList.d.ts} +0 -0
- package/build/ui/{payment → bridge}/Bridge.d.ts +3 -3
- package/build/ui/{payment → bridge}/SelectRecipient.d.ts +0 -0
- package/build/ui/{payment → bridge}/SelectSender.d.ts +2 -2
- package/build/ui/{payment → bridge}/SelectToken.d.ts +1 -1
- /package/build/ui/{payment → profile}/DepositQR.d.ts +0 -0
- /package/build/ui/{payment → profile}/DepositQR.js +0 -0
- /package/src/solana/{wallets.ts → walletStandartList.ts} +0 -0
- /package/src/ui/{payment → profile}/DepositQR.tsx +0 -0
|
@@ -1,25 +1,38 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
-
import styled
|
|
2
|
+
import styled from "styled-components";
|
|
3
3
|
import { observer } from "mobx-react-lite";
|
|
4
4
|
import uuid4 from "uuid4";
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
import RefreshIcon from "../icons/refresh";
|
|
7
7
|
import { ArrowRightIcon } from "../icons/arrow-right";
|
|
8
8
|
|
|
9
|
+
import { HotConnector } from "../../HotConnector";
|
|
10
|
+
import { BridgeReview } from "../../exchange";
|
|
11
|
+
import { OmniWallet } from "../../OmniWallet";
|
|
12
|
+
|
|
9
13
|
import { formatter } from "../../core/utils";
|
|
10
14
|
import { tokens } from "../../core/tokens";
|
|
11
15
|
import { Recipient } from "../../core/recipient";
|
|
12
|
-
import {
|
|
13
|
-
import { BridgeReview } from "../../exchange";
|
|
14
|
-
import { HotConnector } from "../../HotConnector";
|
|
15
|
-
import { WalletType } from "../../core/chains";
|
|
16
|
+
import { chains, WalletType } from "../../core/chains";
|
|
16
17
|
import { Token } from "../../core/token";
|
|
17
18
|
|
|
18
19
|
import Popup from "../Popup";
|
|
19
20
|
import { PopupButton } from "../styles";
|
|
20
|
-
import
|
|
21
|
+
import DepositQR from "../profile/DepositQR";
|
|
22
|
+
import { openSelectRecipient, openSelectSender, openSelectTokenPopup, openWalletPicker } from "../router";
|
|
21
23
|
import { TokenIcon } from "./TokenCard";
|
|
22
|
-
|
|
24
|
+
|
|
25
|
+
import { PLarge, PMedium, PSmall, PTiny } from "../uikit/text";
|
|
26
|
+
import { Skeleton } from "../uikit/loader";
|
|
27
|
+
import { ImageView } from "../uikit/image";
|
|
28
|
+
import ExchangeIcon from "../icons/exchange";
|
|
29
|
+
import { ActionButton, Button } from "../uikit/button";
|
|
30
|
+
|
|
31
|
+
const animations = {
|
|
32
|
+
success: "https://hex.exchange/success.json",
|
|
33
|
+
failed: "https://hex.exchange/error.json",
|
|
34
|
+
loading: "https://hex.exchange/loading.json",
|
|
35
|
+
};
|
|
23
36
|
|
|
24
37
|
export interface BridgeProps {
|
|
25
38
|
hot: HotConnector;
|
|
@@ -48,7 +61,7 @@ const FIXED = 6;
|
|
|
48
61
|
export const Bridge = observer(({ hot, widget, setup, onClose, onProcess, onSelectPair }: BridgeProps) => {
|
|
49
62
|
const [isFiat, setIsFiat] = useState(false);
|
|
50
63
|
const [type, setType] = useState<"exactIn" | "exactOut">(setup?.type || "exactIn");
|
|
51
|
-
const [value, setValue] = useState<string>(setup?.amount?.
|
|
64
|
+
const [value, setValue] = useState<string>(setup?.amount?.toFixed(6) ?? "");
|
|
52
65
|
const [from, setFrom] = useState<Token>(setup?.from || tokens.list.find((t) => t.id === localStorage.getItem("bridge:from")) || tokens.list.find((t) => t.symbol === "NEAR")!);
|
|
53
66
|
const [to, setTo] = useState<Token>(setup?.to || tokens.list.find((t) => t.id === localStorage.getItem("bridge:to")) || tokens.list.find((t) => t.symbol === "USDT")!);
|
|
54
67
|
|
|
@@ -56,6 +69,12 @@ export const Bridge = observer(({ hot, widget, setup, onClose, onProcess, onSele
|
|
|
56
69
|
const [isError, setIsError] = useState<string | null>(null);
|
|
57
70
|
const [isReviewing, setIsReviewing] = useState(false);
|
|
58
71
|
|
|
72
|
+
useState(() => {
|
|
73
|
+
fetch(animations.loading);
|
|
74
|
+
fetch(animations.success);
|
|
75
|
+
fetch(animations.failed);
|
|
76
|
+
});
|
|
77
|
+
|
|
59
78
|
const [processing, setProcessing] = useState<{
|
|
60
79
|
status: "qr" | "processing" | "success" | "error";
|
|
61
80
|
resolve?: (value: BridgeReview) => void;
|
|
@@ -170,9 +189,16 @@ export const Bridge = observer(({ hot, widget, setup, onClose, onProcess, onSele
|
|
|
170
189
|
log("Signing transaction");
|
|
171
190
|
|
|
172
191
|
const result = await hot.exchange.makeSwap(review, { log });
|
|
173
|
-
|
|
192
|
+
let resultReview = result.review;
|
|
193
|
+
|
|
194
|
+
if (result.processing) {
|
|
195
|
+
log("Waiting for transaction to be confirmed");
|
|
196
|
+
resultReview = await result.processing();
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
setProcessing({ status: "success", message: "Transaction signed", review: resultReview });
|
|
174
200
|
if (setup?.autoClose) onClose();
|
|
175
|
-
return
|
|
201
|
+
return resultReview;
|
|
176
202
|
} catch (e) {
|
|
177
203
|
setProcessing({ status: "error", message: e?.toString?.() ?? "Unknown error", review });
|
|
178
204
|
throw e;
|
|
@@ -220,7 +246,7 @@ export const Bridge = observer(({ hot, widget, setup, onClose, onProcess, onSele
|
|
|
220
246
|
<Popup widget={widget} onClose={onClose} header={<p>{title}</p>} mobileFullscreen={setup?.mobileFullscreen}>
|
|
221
247
|
<div style={{ width: "100%", height: 400, display: "flex", justifyContent: "center", alignItems: "center", flexDirection: "column" }}>
|
|
222
248
|
{/* @ts-expect-error: dotlottie-wc is not typed */}
|
|
223
|
-
<dotlottie-wc key="loading" src=
|
|
249
|
+
<dotlottie-wc key="loading" src={animations.loading} speed="1" style={{ width: 300, height: 300 }} mode="forward" loop autoplay></dotlottie-wc>
|
|
224
250
|
<p style={{ marginTop: -32, fontSize: 16 }}>{processing.message}</p>
|
|
225
251
|
</div>
|
|
226
252
|
</Popup>
|
|
@@ -232,7 +258,7 @@ export const Bridge = observer(({ hot, widget, setup, onClose, onProcess, onSele
|
|
|
232
258
|
<Popup widget={widget} onClose={onClose} header={<p>{title}</p>} mobileFullscreen={setup?.mobileFullscreen}>
|
|
233
259
|
<div style={{ width: "100%", height: 400, display: "flex", justifyContent: "center", alignItems: "center", flexDirection: "column" }}>
|
|
234
260
|
{/* @ts-expect-error: dotlottie-wc is not typed */}
|
|
235
|
-
<dotlottie-wc key="success" src=
|
|
261
|
+
<dotlottie-wc key="success" src={animations.success} speed="1" style={{ width: 300, height: 300 }} mode="forward" loop autoplay></dotlottie-wc>
|
|
236
262
|
<p style={{ fontSize: 24, marginTop: -32, fontWeight: "bold" }}>Exchange successful</p>
|
|
237
263
|
</div>
|
|
238
264
|
<PopupButton style={{ marginTop: "auto" }} onClick={() => (cancelReview(), onClose())}>
|
|
@@ -247,11 +273,11 @@ export const Bridge = observer(({ hot, widget, setup, onClose, onProcess, onSele
|
|
|
247
273
|
<Popup widget={widget} onClose={onClose} header={<p>{title}</p>} mobileFullscreen={setup?.mobileFullscreen}>
|
|
248
274
|
<div style={{ width: "100%", height: 400, gap: 8, display: "flex", justifyContent: "center", alignItems: "center", flexDirection: "column" }}>
|
|
249
275
|
{/* @ts-expect-error: dotlottie-wc is not typed */}
|
|
250
|
-
<dotlottie-wc key="error" src=
|
|
276
|
+
<dotlottie-wc key="error" src={animations.failed} speed="1" style={{ width: 300, height: 300 }} mode="forward" loop autoplay></dotlottie-wc>
|
|
251
277
|
<p style={{ fontSize: 24, marginTop: -32, fontWeight: "bold" }}>Exchange failed</p>
|
|
252
278
|
<p style={{ fontSize: 14 }}>{processing.message}</p>
|
|
253
279
|
</div>
|
|
254
|
-
<
|
|
280
|
+
<ActionButton onClick={() => (cancelReview(), onClose())}>Continue</ActionButton>
|
|
255
281
|
</Popup>
|
|
256
282
|
);
|
|
257
283
|
}
|
|
@@ -261,94 +287,125 @@ export const Bridge = observer(({ hot, widget, setup, onClose, onProcess, onSele
|
|
|
261
287
|
if (recipient == null) return <PopupButton disabled>Set recipient</PopupButton>;
|
|
262
288
|
if (sender !== "qr" && +from.float(hot.balance(sender, from)).toFixed(FIXED) < +amountFrom.toFixed(FIXED)) return <PopupButton disabled>Insufficient balance</PopupButton>;
|
|
263
289
|
return (
|
|
264
|
-
<
|
|
290
|
+
<ActionButton style={{ width: "100%", marginTop: 40 }} disabled={isReviewing || isError != null} onClick={handleConfirm}>
|
|
265
291
|
{isReviewing ? "Quoting..." : isError != null ? isError : "Confirm"}
|
|
266
|
-
</
|
|
292
|
+
</ActionButton>
|
|
267
293
|
);
|
|
268
294
|
};
|
|
269
295
|
|
|
270
296
|
return (
|
|
271
|
-
<Popup widget={widget} onClose={onClose} header={<p>{title}</p>} mobileFullscreen={setup?.mobileFullscreen}>
|
|
272
|
-
<div style={{ display: "flex", flexDirection: "column", gap:
|
|
273
|
-
<Card>
|
|
274
|
-
<
|
|
297
|
+
<Popup widget={widget} onClose={onClose} header={<p>{title}</p>} mobileFullscreen={setup?.mobileFullscreen} style={{ background: "#191919" }}>
|
|
298
|
+
<div style={{ display: "flex", flexDirection: "column", gap: 4, width: "100%", height: "100%" }}>
|
|
299
|
+
<Card style={{ borderRadius: "20px 20px 2px 2px" }}>
|
|
300
|
+
<CardHeader>
|
|
301
|
+
<ChainButton onClick={() => openSelectTokenPopup({ hot, onSelect: (token, wallet) => (setFrom(token), setSender(wallet)) })}>
|
|
302
|
+
<PSmall>From</PSmall>
|
|
303
|
+
<ImageView src={chains.get(from.chain)?.logo || ""} alt={from.symbol} size={16} />
|
|
304
|
+
<PSmall>{chains.get(from.chain)?.name}</PSmall>
|
|
305
|
+
<ArrowRightIcon style={{ marginLeft: -8, transform: "rotate(-270deg)" }} color="#ababab" />
|
|
306
|
+
</ChainButton>
|
|
307
|
+
|
|
275
308
|
<div style={{ display: "flex", alignItems: "center", gap: 8 }}>
|
|
276
|
-
<
|
|
277
|
-
<BadgeButton
|
|
278
|
-
|
|
309
|
+
<PSmall>Sender:</PSmall>
|
|
310
|
+
<BadgeButton
|
|
311
|
+
onClick={() => {
|
|
312
|
+
if (from.type === WalletType.OMNI) openSelectSender({ hot, type: from.type, onSelect: (sender) => setSender(sender) });
|
|
313
|
+
else openWalletPicker(hot.getWalletConnector(from.type)!, (wallet) => setSender(wallet));
|
|
314
|
+
}}
|
|
315
|
+
>
|
|
316
|
+
<PSmall>{sender == null ? "Select" : sender !== "qr" ? formatter.truncateAddress(sender.address, 8) : "QR"}</PSmall>
|
|
279
317
|
</BadgeButton>
|
|
280
318
|
</div>
|
|
281
|
-
</
|
|
282
|
-
|
|
283
|
-
<
|
|
284
|
-
<
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
{isReviewing && type === "exactOut" ? (
|
|
291
|
-
<SkeletonShine />
|
|
292
|
-
) : (
|
|
293
|
-
<input //
|
|
294
|
-
name="from"
|
|
295
|
-
type="text"
|
|
296
|
-
className="input"
|
|
297
|
-
autoComplete="off"
|
|
298
|
-
autoCapitalize="off"
|
|
299
|
-
autoCorrect="off"
|
|
300
|
-
readOnly={setup?.readonlyAmount}
|
|
301
|
-
value={isFiat ? `$${showAmountFrom}` : showAmountFrom}
|
|
302
|
-
onChange={(e) => (setType("exactIn"), setValue(e.target.value))}
|
|
303
|
-
placeholder="0"
|
|
304
|
-
autoFocus
|
|
319
|
+
</CardHeader>
|
|
320
|
+
|
|
321
|
+
<CardBody>
|
|
322
|
+
<div style={{ width: "100%", display: "flex", alignItems: "center", gap: 8, justifyContent: "space-between" }}>
|
|
323
|
+
<TokenPreview //
|
|
324
|
+
onSelect={() => openSelectTokenPopup({ onSelect: (token, wallet) => (setFrom(token), setSender(wallet)), initialChain: from.chain, hot })}
|
|
325
|
+
style={{ pointerEvents: setup?.readonlyFrom ? "none" : "all" }}
|
|
326
|
+
token={from}
|
|
305
327
|
/>
|
|
306
|
-
)}
|
|
307
|
-
</div>
|
|
308
|
-
|
|
309
|
-
{isFiat && (
|
|
310
|
-
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", width: "100%" }}>
|
|
311
|
-
{sender !== "qr" && (
|
|
312
|
-
<AvailableBalance>
|
|
313
|
-
<p>Balance: ${from.readable(availableBalance, from.usd)}</p>
|
|
314
|
-
<RefreshButton onClick={() => sender && hot.fetchToken(from, sender)} />
|
|
315
|
-
</AvailableBalance>
|
|
316
|
-
)}
|
|
317
328
|
|
|
318
|
-
{
|
|
329
|
+
{isReviewing && type === "exactOut" ? (
|
|
330
|
+
<Skeleton />
|
|
331
|
+
) : (
|
|
332
|
+
<input //
|
|
333
|
+
name="from"
|
|
334
|
+
type="text"
|
|
335
|
+
className="input"
|
|
336
|
+
autoComplete="off"
|
|
337
|
+
autoCapitalize="off"
|
|
338
|
+
autoCorrect="off"
|
|
339
|
+
readOnly={setup?.readonlyAmount}
|
|
340
|
+
value={isFiat ? `$${showAmountFrom}` : showAmountFrom}
|
|
341
|
+
onChange={(e) => (setType("exactIn"), setValue(e.target.value))}
|
|
342
|
+
placeholder="0"
|
|
343
|
+
autoFocus
|
|
344
|
+
/>
|
|
345
|
+
)}
|
|
346
|
+
</div>
|
|
319
347
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
{
|
|
323
|
-
<
|
|
324
|
-
|
|
325
|
-
|
|
348
|
+
{isFiat && (
|
|
349
|
+
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", width: "100%" }}>
|
|
350
|
+
{sender !== "qr" && (
|
|
351
|
+
<AvailableBalance>
|
|
352
|
+
<PSmall>Balance: ${from.readable(availableBalance, from.usd)}</PSmall>
|
|
353
|
+
<Button onClick={() => sender && hot.fetchToken(from, sender)}>
|
|
354
|
+
<RefreshIcon color="#fff" />
|
|
355
|
+
</Button>
|
|
356
|
+
</AvailableBalance>
|
|
326
357
|
)}
|
|
327
|
-
|
|
358
|
+
|
|
359
|
+
{sender === "qr" && <div />}
|
|
360
|
+
|
|
361
|
+
<div style={{ display: "flex", alignItems: "center", gap: 4, flexShrink: 0 }}>
|
|
362
|
+
{from.usd !== 0 && <PSmall style={{ marginRight: 8 }}>{`${from.readable(amountFrom / from.usd)} ${from.symbol}`}</PSmall>}
|
|
363
|
+
|
|
364
|
+
{from.usd !== 0 && (
|
|
365
|
+
<BadgeButton style={{ border: `1px solid #fff` }} onClick={() => setIsFiat(!isFiat)}>
|
|
366
|
+
<PTiny>USD</PTiny>
|
|
367
|
+
</BadgeButton>
|
|
368
|
+
)}
|
|
369
|
+
|
|
370
|
+
{sender !== "qr" && (
|
|
371
|
+
<BadgeButton onClick={handleMax}>
|
|
372
|
+
<PTiny>MAX</PTiny>
|
|
373
|
+
</BadgeButton>
|
|
374
|
+
)}
|
|
375
|
+
</div>
|
|
328
376
|
</div>
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
377
|
+
)}
|
|
378
|
+
|
|
379
|
+
{!isFiat && (
|
|
380
|
+
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", width: "100%" }}>
|
|
381
|
+
{sender !== "qr" && (
|
|
382
|
+
<AvailableBalance>
|
|
383
|
+
<PSmall>Balance: {`${from.readable(availableBalance)} ${from.symbol}`}</PSmall>
|
|
384
|
+
<Button style={{ marginTop: 2 }} onClick={() => sender && hot.fetchToken(from, sender)}>
|
|
385
|
+
<RefreshIcon color="#fff" />
|
|
386
|
+
</Button>
|
|
387
|
+
</AvailableBalance>
|
|
388
|
+
)}
|
|
389
|
+
{sender === "qr" && <div />}
|
|
390
|
+
<div style={{ display: "flex", alignItems: "center", gap: 4 }}>
|
|
391
|
+
{from.usd !== 0 && <PSmall style={{ marginRight: 8 }}>${from.readable(amountFrom, from.usd)}</PSmall>}
|
|
392
|
+
{from.usd !== 0 && (
|
|
393
|
+
<BadgeButton onClick={() => setIsFiat(!isFiat)}>
|
|
394
|
+
<PTiny>USD</PTiny>
|
|
395
|
+
</BadgeButton>
|
|
396
|
+
)}
|
|
397
|
+
{sender !== "qr" && (
|
|
398
|
+
<BadgeButton onClick={handleMax}>
|
|
399
|
+
<PTiny>MAX</PTiny>
|
|
400
|
+
</BadgeButton>
|
|
401
|
+
)}
|
|
402
|
+
</div>
|
|
345
403
|
</div>
|
|
346
|
-
|
|
347
|
-
|
|
404
|
+
)}
|
|
405
|
+
</CardBody>
|
|
348
406
|
</Card>
|
|
349
407
|
|
|
350
|
-
<div style={{ position: "relative" }}>
|
|
351
|
-
<div style={{ width: "100%", height: 1, backgroundColor: "rgba(255, 255, 255, 0.07)" }} />
|
|
408
|
+
<div style={{ position: "relative", height: 1, width: "100%" }}>
|
|
352
409
|
<SwitchButton
|
|
353
410
|
onClick={() => {
|
|
354
411
|
setFrom(to);
|
|
@@ -359,57 +416,72 @@ export const Bridge = observer(({ hot, widget, setup, onClose, onProcess, onSele
|
|
|
359
416
|
setValue("");
|
|
360
417
|
}}
|
|
361
418
|
>
|
|
362
|
-
<
|
|
419
|
+
<ExchangeIcon color="#fff" width={22} height={22} style={{ flexShrink: 0, transform: "rotate(270deg)" }} />
|
|
363
420
|
</SwitchButton>
|
|
364
421
|
</div>
|
|
365
422
|
|
|
366
|
-
<Card>
|
|
367
|
-
<
|
|
423
|
+
<Card style={{ borderRadius: "2px 2px 20px 20px" }}>
|
|
424
|
+
<CardHeader>
|
|
425
|
+
<ChainButton onClick={() => openSelectTokenPopup({ hot, onSelect: (token, wallet) => (setTo(token), setRecipient(wallet)) })}>
|
|
426
|
+
<PSmall>To</PSmall>
|
|
427
|
+
<ImageView src={chains.get(to.chain)?.logo || ""} alt={to.symbol} size={16} />
|
|
428
|
+
<PSmall>{chains.get(to.chain)?.name}</PSmall>
|
|
429
|
+
<ArrowRightIcon style={{ marginLeft: -8, transform: "rotate(-270deg)" }} color="#ababab" />
|
|
430
|
+
</ChainButton>
|
|
431
|
+
|
|
368
432
|
<div style={{ display: "flex", alignItems: "center", gap: 8 }}>
|
|
369
|
-
<
|
|
370
|
-
<BadgeButton
|
|
371
|
-
|
|
433
|
+
<PSmall>Recipient:</PSmall>
|
|
434
|
+
<BadgeButton
|
|
435
|
+
onClick={() => {
|
|
436
|
+
if (to.type === WalletType.OMNI) openSelectRecipient({ hot, type: to.type, onSelect: (recipient) => setRecipient(recipient) });
|
|
437
|
+
else openWalletPicker(hot.getWalletConnector(to.type)!, (wallet) => setRecipient(Recipient.fromWallet(wallet)));
|
|
438
|
+
}}
|
|
439
|
+
>
|
|
440
|
+
<PSmall>{recipient == null ? "Select" : formatter.truncateAddress(recipient.address, 8)}</PSmall>
|
|
372
441
|
</BadgeButton>
|
|
373
442
|
</div>
|
|
374
|
-
</
|
|
375
|
-
|
|
376
|
-
<
|
|
377
|
-
<
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
{isReviewing && type === "exactIn" ? (
|
|
392
|
-
<SkeletonShine />
|
|
393
|
-
) : (
|
|
394
|
-
<input //
|
|
395
|
-
name="to"
|
|
396
|
-
type="text"
|
|
397
|
-
className="input"
|
|
398
|
-
autoComplete="off"
|
|
399
|
-
autoCapitalize="off"
|
|
400
|
-
autoCorrect="off"
|
|
401
|
-
readOnly={setup?.readonlyAmount}
|
|
402
|
-
value={isFiat ? `$${+(+showAmountTo * to.usd).toFixed(FIXED)}` : showAmountTo}
|
|
403
|
-
onChange={(e) => (setType("exactOut"), setValue(e.target.value))}
|
|
404
|
-
placeholder="0"
|
|
443
|
+
</CardHeader>
|
|
444
|
+
|
|
445
|
+
<CardBody style={{ borderRadius: "0 0 20px 20px" }}>
|
|
446
|
+
<div style={{ width: "100%", display: "flex", alignItems: "center", gap: 8, justifyContent: "space-between" }}>
|
|
447
|
+
<TokenPreview //
|
|
448
|
+
token={to}
|
|
449
|
+
style={{ pointerEvents: setup?.readonlyTo ? "none" : "all" }}
|
|
450
|
+
onSelect={() =>
|
|
451
|
+
openSelectTokenPopup({
|
|
452
|
+
hot,
|
|
453
|
+
initialChain: to.chain,
|
|
454
|
+
onSelect: (token, wallet) => {
|
|
455
|
+
setRecipient(wallet ? Recipient.fromWallet(wallet) : undefined);
|
|
456
|
+
setTo(token);
|
|
457
|
+
},
|
|
458
|
+
})
|
|
459
|
+
}
|
|
405
460
|
/>
|
|
406
|
-
)}
|
|
407
|
-
</div>
|
|
408
461
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
462
|
+
{isReviewing && type === "exactIn" ? (
|
|
463
|
+
<Skeleton />
|
|
464
|
+
) : (
|
|
465
|
+
<input //
|
|
466
|
+
name="to"
|
|
467
|
+
type="text"
|
|
468
|
+
className="input"
|
|
469
|
+
autoComplete="off"
|
|
470
|
+
autoCapitalize="off"
|
|
471
|
+
autoCorrect="off"
|
|
472
|
+
readOnly={setup?.readonlyAmount}
|
|
473
|
+
value={isFiat ? `$${+(+showAmountTo * to.usd).toFixed(FIXED)}` : showAmountTo}
|
|
474
|
+
onChange={(e) => (setType("exactOut"), setValue(e.target.value))}
|
|
475
|
+
placeholder="0"
|
|
476
|
+
/>
|
|
477
|
+
)}
|
|
478
|
+
</div>
|
|
479
|
+
|
|
480
|
+
<div style={{ width: "100%", display: "flex", justifyContent: "flex-end", marginTop: -4 }}>
|
|
481
|
+
{isFiat && <PSmall>To receive: ${`${to.readable(amountTo ?? 0)} ${to.symbol}`}</PSmall>}
|
|
482
|
+
{!isFiat && <PSmall>To receive: ${to.readable(amountTo ?? 0, to.usd)}</PSmall>}
|
|
483
|
+
</div>
|
|
484
|
+
</CardBody>
|
|
413
485
|
</Card>
|
|
414
486
|
|
|
415
487
|
<div style={{ marginTop: "auto" }}>{button()}</div>
|
|
@@ -421,50 +493,60 @@ export const Bridge = observer(({ hot, widget, setup, onClose, onProcess, onSele
|
|
|
421
493
|
const TokenPreview = ({ style, token, onSelect }: { style?: React.CSSProperties; token: Token; onSelect: (token: Token) => void }) => {
|
|
422
494
|
return (
|
|
423
495
|
<SelectTokenButton style={style} onClick={() => onSelect(token)}>
|
|
424
|
-
<TokenIcon token={token} />
|
|
425
|
-
<
|
|
496
|
+
<TokenIcon withoutChain token={token} size={32} />
|
|
497
|
+
<PLarge>{token.symbol}</PLarge>
|
|
426
498
|
<ArrowRightIcon style={{ flexShrink: 0, position: "absolute", right: 4 }} />
|
|
427
499
|
</SelectTokenButton>
|
|
428
500
|
);
|
|
429
501
|
};
|
|
430
502
|
|
|
431
503
|
const BadgeButton = styled.button`
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
background: #282c30;
|
|
504
|
+
display: flex;
|
|
505
|
+
border-radius: 8px;
|
|
506
|
+
border: 1px solid #323232;
|
|
436
507
|
padding: 4px 8px;
|
|
437
|
-
|
|
508
|
+
background: transparent;
|
|
509
|
+
transition: 0.2s border-color;
|
|
438
510
|
cursor: pointer;
|
|
439
511
|
outline: none;
|
|
440
|
-
|
|
441
|
-
border: 1px solid transparent;
|
|
442
|
-
transition: 0.2s border-color;
|
|
512
|
+
gap: 4px;
|
|
443
513
|
|
|
444
514
|
&:hover {
|
|
445
515
|
border-color: #4e4e4e;
|
|
446
516
|
}
|
|
517
|
+
`;
|
|
447
518
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
519
|
+
const ChainButton = styled.button`
|
|
520
|
+
display: flex;
|
|
521
|
+
align-items: center;
|
|
522
|
+
padding: 0;
|
|
523
|
+
gap: 8px;
|
|
524
|
+
flex-shrink: 0;
|
|
525
|
+
cursor: pointer;
|
|
526
|
+
outline: none;
|
|
527
|
+
border: none;
|
|
528
|
+
background: transparent;
|
|
529
|
+
transition: 0.2s opacity;
|
|
530
|
+
|
|
531
|
+
&:hover {
|
|
532
|
+
opacity: 0.8;
|
|
451
533
|
}
|
|
452
534
|
`;
|
|
453
535
|
|
|
454
536
|
const SelectTokenButton = styled.button`
|
|
455
537
|
display: flex;
|
|
456
538
|
align-items: center;
|
|
457
|
-
gap:
|
|
539
|
+
gap: 8px;
|
|
458
540
|
flex-shrink: 0;
|
|
459
541
|
cursor: pointer;
|
|
460
542
|
outline: none;
|
|
461
543
|
border: none;
|
|
462
544
|
position: relative;
|
|
463
545
|
background: transparent;
|
|
464
|
-
border-radius:
|
|
465
|
-
padding:
|
|
466
|
-
padding-right:
|
|
467
|
-
margin: -
|
|
546
|
+
border-radius: 24px;
|
|
547
|
+
padding: 4px;
|
|
548
|
+
padding-right: 28px;
|
|
549
|
+
margin: -4px;
|
|
468
550
|
max-width: 160px;
|
|
469
551
|
transition: 0.2s background-color;
|
|
470
552
|
|
|
@@ -482,10 +564,10 @@ const SelectTokenButton = styled.button`
|
|
|
482
564
|
const AvailableBalance = styled.div`
|
|
483
565
|
display: flex;
|
|
484
566
|
align-items: center;
|
|
485
|
-
gap: 4;
|
|
486
567
|
overflow: hidden;
|
|
487
568
|
max-width: 200px;
|
|
488
569
|
white-space: nowrap;
|
|
570
|
+
gap: 4px;
|
|
489
571
|
|
|
490
572
|
p {
|
|
491
573
|
overflow: hidden;
|
|
@@ -495,15 +577,17 @@ const AvailableBalance = styled.div`
|
|
|
495
577
|
`;
|
|
496
578
|
|
|
497
579
|
const Card = styled.div`
|
|
498
|
-
display: flex;
|
|
499
|
-
width: 100%;
|
|
500
|
-
flex-direction: column;
|
|
501
|
-
gap: 16px;
|
|
502
|
-
width: 100%;
|
|
503
580
|
text-align: left;
|
|
504
581
|
align-items: flex-start;
|
|
505
582
|
justify-content: center;
|
|
506
|
-
|
|
583
|
+
flex-direction: column;
|
|
584
|
+
|
|
585
|
+
display: flex;
|
|
586
|
+
width: 100%;
|
|
587
|
+
|
|
588
|
+
border-radius: 20px 20px 2px 2px;
|
|
589
|
+
border: 1px solid #323232;
|
|
590
|
+
background: #1f1f1f;
|
|
507
591
|
|
|
508
592
|
input {
|
|
509
593
|
outline: none;
|
|
@@ -525,77 +609,47 @@ const Card = styled.div`
|
|
|
525
609
|
}
|
|
526
610
|
`;
|
|
527
611
|
|
|
612
|
+
const CardHeader = styled.div`
|
|
613
|
+
display: flex;
|
|
614
|
+
align-items: center;
|
|
615
|
+
justify-content: space-between;
|
|
616
|
+
padding: 8px 16px;
|
|
617
|
+
width: 100%;
|
|
618
|
+
gap: 8px;
|
|
619
|
+
`;
|
|
620
|
+
|
|
621
|
+
const CardBody = styled.div`
|
|
622
|
+
padding: 16px;
|
|
623
|
+
width: 100%;
|
|
624
|
+
flex-direction: column;
|
|
625
|
+
align-items: flex-start;
|
|
626
|
+
border-radius: 20px 20px 0 0;
|
|
627
|
+
border-top: 1px solid #323232;
|
|
628
|
+
background: #272727;
|
|
629
|
+
display: flex;
|
|
630
|
+
gap: 8px;
|
|
631
|
+
`;
|
|
632
|
+
|
|
528
633
|
const SwitchButton = styled.button`
|
|
529
634
|
position: absolute;
|
|
530
635
|
left: 50%;
|
|
531
636
|
top: -18px;
|
|
532
637
|
transform: translate(-50%, 0);
|
|
533
638
|
background: #232323;
|
|
639
|
+
|
|
534
640
|
border-radius: 50%;
|
|
535
641
|
width: 36px;
|
|
536
642
|
height: 36px;
|
|
643
|
+
|
|
537
644
|
display: flex;
|
|
538
645
|
align-items: center;
|
|
539
646
|
justify-content: center;
|
|
647
|
+
|
|
540
648
|
z-index: 2;
|
|
541
649
|
cursor: pointer;
|
|
542
|
-
border: 2px solid #181818;
|
|
543
|
-
box-shadow: 0 2px 8px 0 #18181870;
|
|
544
650
|
outline: none;
|
|
545
|
-
border: none;
|
|
546
|
-
cursor: pointer;
|
|
547
|
-
`;
|
|
548
651
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
}
|
|
553
|
-
100% {
|
|
554
|
-
background-position: calc(200px + 100%) 0;
|
|
555
|
-
}
|
|
652
|
+
border-radius: 24px;
|
|
653
|
+
border: 4px solid #191919;
|
|
654
|
+
background: #323232;
|
|
556
655
|
`;
|
|
557
|
-
|
|
558
|
-
const SkeletonShine = styled.div`
|
|
559
|
-
display: inline-block;
|
|
560
|
-
width: 100px;
|
|
561
|
-
height: 40px;
|
|
562
|
-
border-radius: 8px;
|
|
563
|
-
background: #2e2e2e;
|
|
564
|
-
position: relative;
|
|
565
|
-
overflow: hidden;
|
|
566
|
-
|
|
567
|
-
&:after {
|
|
568
|
-
content: "";
|
|
569
|
-
display: block;
|
|
570
|
-
height: 100%;
|
|
571
|
-
width: 100%;
|
|
572
|
-
position: absolute;
|
|
573
|
-
top: 0;
|
|
574
|
-
left: 0;
|
|
575
|
-
background: linear-gradient(90deg, rgba(34, 34, 34, 0) 0%, rgba(255, 255, 255, 0.06) 40%, rgba(255, 255, 255, 0.12) 50%, rgba(255, 255, 255, 0.06) 60%, rgba(34, 34, 34, 0) 100%);
|
|
576
|
-
background-size: 200px 100%;
|
|
577
|
-
animation: ${shine} 1.4s infinite linear;
|
|
578
|
-
}
|
|
579
|
-
`;
|
|
580
|
-
|
|
581
|
-
const RefreshButton = ({ onClick }: { onClick: () => void }) => {
|
|
582
|
-
return (
|
|
583
|
-
<svg
|
|
584
|
-
onClick={onClick}
|
|
585
|
-
style={{ width: 18, height: 18, verticalAlign: "middle", marginLeft: 8, cursor: "pointer", opacity: 0.7, transition: "opacity 0.2s" }}
|
|
586
|
-
viewBox="0 0 24 24"
|
|
587
|
-
fill="none"
|
|
588
|
-
stroke="#fff"
|
|
589
|
-
strokeWidth="2"
|
|
590
|
-
strokeLinecap="round"
|
|
591
|
-
strokeLinejoin="round"
|
|
592
|
-
onMouseOver={(e) => (e.currentTarget.style.opacity = "1")}
|
|
593
|
-
onMouseOut={(e) => (e.currentTarget.style.opacity = "0.7")}
|
|
594
|
-
>
|
|
595
|
-
<path d="M23 4v6h-6" />
|
|
596
|
-
<path d="M1 20v-6h6" />
|
|
597
|
-
<path d="M3.51 9a9 9 0 0114.13-3.36L23 10" />
|
|
598
|
-
<path d="M20.49 15a9 9 0 01-14.13 3.36L1 14" />
|
|
599
|
-
</svg>
|
|
600
|
-
);
|
|
601
|
-
};
|