Skip to content

Commit 9e0c398

Browse files
committed
fix: smooth claim status loading
1 parent 33af51a commit 9e0c398

3 files changed

Lines changed: 56 additions & 16 deletions

File tree

app/globals.css

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,6 +1658,22 @@ body.page--article h1 {
16581658
font-weight: 650;
16591659
}
16601660

1661+
.claim-amount__loading {
1662+
display: inline-flex;
1663+
align-items: center;
1664+
min-height: 2rem;
1665+
gap: 0.55rem;
1666+
color: var(--muted);
1667+
font-size: 0.98rem;
1668+
font-weight: 650;
1669+
}
1670+
1671+
.claim-amount__loading .spinner {
1672+
display: inline-block;
1673+
border-color: rgba(47, 103, 195, 0.2);
1674+
border-top-color: #2f67c3;
1675+
}
1676+
16611677
.muted {
16621678
color: var(--muted);
16631679
font-size: 0.92rem;

app/migration/ClaimClient.jsx

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,14 @@ function getErrorMessage(error) {
7171
}
7272

7373
export default function ClaimClient() {
74-
const { address, chainId, isConnected } = useAccount();
74+
const { address, chainId, isConnected, status: accountStatus } = useAccount();
7575
const { switchChainAsync, isPending: isSwitchingNetwork } = useSwitchChain();
7676
const { writeContractAsync, isPending: isConfirmingInWallet } = useWriteContract();
7777

7878
const [airdropConfig, setAirdropConfig] = useState(DEFAULT_CONFIG);
7979
const [merkle, setMerkle] = useState(null);
8080
const [loadError, setLoadError] = useState("");
81+
const [isAirdropDataLoading, setIsAirdropDataLoading] = useState(true);
8182
const [claimMessage, setClaimMessage] = useState("");
8283
const [claimState, setClaimState] = useState("idle");
8384

@@ -97,6 +98,13 @@ export default function ClaimClient() {
9798
const normalizedAccount = normalizeAddress(address);
9899
const entry = normalizedAccount ? merkle?.entries?.[normalizedAccount] || null : null;
99100
const wrongNetwork = Boolean(isConnected && chainId && chainId !== requiredChainId);
101+
const shouldReadClaimed =
102+
Boolean(address) &&
103+
Boolean(entry) &&
104+
isConfigured &&
105+
isConnected &&
106+
!wrongNetwork &&
107+
claimState !== "success";
100108

101109
const {
102110
data: hasClaimed,
@@ -109,13 +117,7 @@ export default function ClaimClient() {
109117
args: address ? [address] : undefined,
110118
chainId: requiredChainId,
111119
query: {
112-
enabled:
113-
Boolean(address) &&
114-
Boolean(entry) &&
115-
isConfigured &&
116-
isConnected &&
117-
!wrongNetwork &&
118-
claimState !== "success",
120+
enabled: shouldReadClaimed,
119121
},
120122
});
121123

@@ -124,6 +126,7 @@ export default function ClaimClient() {
124126

125127
async function loadAirdropData() {
126128
setLoadError("");
129+
setIsAirdropDataLoading(true);
127130

128131
try {
129132
const configResponse = await fetch("/airdrop.config.json", { cache: "no-store" });
@@ -152,10 +155,12 @@ export default function ClaimClient() {
152155

153156
if (!cancelled) {
154157
setMerkle({ ...loadedMerkle, entries: normalizedEntries });
158+
setIsAirdropDataLoading(false);
155159
}
156160
} catch (error) {
157161
if (!cancelled) {
158162
setLoadError(getErrorMessage(error));
163+
setIsAirdropDataLoading(false);
159164
}
160165
}
161166
}
@@ -209,14 +214,20 @@ export default function ClaimClient() {
209214
}, [address, contractAddress, entry, publicClient, refetchClaimed, requiredChainId, writeContractAsync]);
210215

211216
const isClaiming = claimState === "claiming" || isConfirmingInWallet;
217+
const isWalletStatusSettling = accountStatus === "connecting" || accountStatus === "reconnecting";
212218
const claimableHuman = entry ? formatTokenAmount(entry.amount) : "0";
213219
const isAlreadyClaimed = Boolean(hasClaimed || claimState === "success");
220+
const isClaimStatusLoading = shouldReadClaimed && hasClaimed === undefined && !claimedReadError;
221+
const isAmountLoading = isAirdropDataLoading || isWalletStatusSettling || isClaimStatusLoading;
214222
const canClaim =
215223
isConfigured &&
216224
isConnected &&
217225
!wrongNetwork &&
218226
Boolean(merkle) &&
219227
Boolean(entry) &&
228+
!isAirdropDataLoading &&
229+
!isWalletStatusSettling &&
230+
!isClaimStatusLoading &&
220231
!isAlreadyClaimed &&
221232
!claimedReadError &&
222233
!isClaiming;
@@ -226,10 +237,14 @@ export default function ClaimClient() {
226237

227238
let hint = claimMessage;
228239
if (!hint) {
229-
if (!isConfigured) {
240+
if (isAirdropDataLoading) {
241+
hint = "Loading eligibility data...";
242+
} else if (!isConfigured) {
230243
hint = "Migration is not configured yet.";
231244
} else if (loadError) {
232245
hint = loadError;
246+
} else if (isWalletStatusSettling) {
247+
hint = "Loading wallet...";
233248
} else if (!isConnected) {
234249
hint = "Connect your wallet to check eligibility.";
235250
} else if (wrongNetwork) {
@@ -238,6 +253,8 @@ export default function ClaimClient() {
238253
hint = "Loading eligibility data...";
239254
} else if (!entry) {
240255
hint = "This wallet is not eligible for migration.";
256+
} else if (isClaimStatusLoading) {
257+
hint = "Checking claim status...";
241258
} else if (isAlreadyClaimed) {
242259
hint = "You've already claimed with this wallet.";
243260
} else if (claimedReadError) {
@@ -298,10 +315,17 @@ export default function ClaimClient() {
298315
<div className="claim-label">Migration amount</div>
299316
<div className="claim-value">
300317
<div className="claim-amount">
301-
<div className="claim-amount__primary">
302-
<span>{claimableHuman}</span>
303-
<span className="claim-amount__unit">$RSS3</span>
304-
</div>
318+
{isAmountLoading ? (
319+
<div className="claim-amount__loading" role="status" aria-label="Loading migration amount">
320+
<span className="spinner is-on" aria-hidden="true" />
321+
<span>Loading</span>
322+
</div>
323+
) : (
324+
<div className="claim-amount__primary">
325+
<span>{claimableHuman}</span>
326+
<span className="claim-amount__unit">$RSS3</span>
327+
</div>
328+
)}
305329
</div>
306330
</div>
307331
</div>

app/migration/ClaimIsland.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ function ClaimFallback() {
3535
<div className="claim-label">Migration amount</div>
3636
<div className="claim-value">
3737
<div className="claim-amount">
38-
<div className="claim-amount__primary">
39-
<span>0</span>
40-
<span className="claim-amount__unit">$RSS3</span>
38+
<div className="claim-amount__loading" role="status" aria-label="Loading migration amount">
39+
<span className="spinner is-on" aria-hidden="true" />
40+
<span>Loading</span>
4141
</div>
4242
</div>
4343
</div>

0 commit comments

Comments
 (0)