Skip to content

Commit

Permalink
feat(bridge-ui): retry dialog (#16536)
Browse files Browse the repository at this point in the history
  • Loading branch information
KorbinianK authored Mar 27, 2024
1 parent 0c5aba2 commit 3beba21
Show file tree
Hide file tree
Showing 10 changed files with 338 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { switchChain } from '@wagmi/core';
import { log } from 'debug';
import { createEventDispatcher } from 'svelte';
import type { Hash } from 'viem';
import { bridges, type BridgeTransaction } from '$libs/bridge';
import { NotConnectedError } from '$libs/error';
Expand All @@ -10,6 +11,9 @@
import { account } from '$stores/account';
import { connectedSourceChain } from '$stores/network';
import { selectedRetryMethod } from './RetryDialog/state';
import { RETRY_OPTION } from './RetryDialog/types';
const dispatch = createEventDispatcher();
export let bridgeTx: BridgeTransaction;
Expand Down Expand Up @@ -49,7 +53,13 @@
log(`Claiming ${bridgeTx.tokenType} for transaction`, bridgeTx);
// Step 4: Call claim() method on the bridge
const txHash = await bridge.claim({ wallet, bridgeTx });
let txHash: Hash;
if ($selectedRetryMethod === RETRY_OPTION.RETRY_ONCE) {
log('Claiming with lastAttempt flag');
txHash = await bridge.claim({ wallet, bridgeTx, lastAttempt: true });
} else {
txHash = await bridge.claim({ wallet, bridgeTx });
}
dispatch('claimingTxSent', { txHash, type: 'claim' });
} catch (err) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,36 +52,35 @@
export let nft: NFT | null = null;
export let proofReceipt: GetProofReceiptResponse;
export let activeStep: ClaimSteps = INITIAL_STEP;
export let bridgeTx: BridgeTransaction;
export const handleClaimClick = async () => {
claiming = true;
await ClaimComponent.claim();
// claiming = false;
};
const handleAccountChange = () => {
activeStep = INITIAL_STEP;
};
let canContinue = false;
export let proofReceipt: GetProofReceiptResponse;
let claiming: boolean;
let claimingDone = false;
let ClaimComponent: Claim;
let txHash: Hash;
const handleAccountChange = () => {
activeStep = INITIAL_STEP;
};
const closeDialog = () => {
dialogOpen = false;
reset();
};
let ClaimComponent: Claim;
export let activeStep: ClaimSteps = INITIAL_STEP;
export let bridgeTx: BridgeTransaction;
const handleClaimTxSent = async (event: CustomEvent<{ txHash: Hash; type: ClaimTypes }>) => {
const { txHash, type } = event.detail;
const { txHash: transactionHash, type } = event.detail;
txHash = transactionHash;
log('handle claim tx sent', txHash, type);
claiming = true;
Expand Down Expand Up @@ -135,10 +134,6 @@
}),
});
}
//TODO: this could be just step 1 of 2, change text accordingly
// claiming = false;
};
const handleClaimError = (event: CustomEvent<{ error: unknown; type: ClaimTypes }>) => {
Expand Down Expand Up @@ -252,7 +247,7 @@
<DialogStep
stepIndex={ClaimSteps.REVIEW}
currentStepIndex={activeStep}
isActive={activeStep === ClaimSteps.REVIEW}>{$t('transactions.claim.steps.review.name')}</DialogStep>
isActive={activeStep === ClaimSteps.REVIEW}>{$t('common.review')}</DialogStep>
<DialogStep
stepIndex={ClaimSteps.CONFIRM}
currentStepIndex={activeStep}
Expand All @@ -270,6 +265,8 @@
<ClaimReviewStep tx={bridgeTx} {nft} />
{:else if activeStep === ClaimSteps.CONFIRM}
<ClaimConfirmStep
{bridgeTx}
bind:txHash
on:claim={handleClaimClick}
bind:claiming
bind:canClaim={canContinue}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import { t } from 'svelte-i18n';
import type { Hash } from 'viem';
import { chainConfig } from '$chainConfig';
import ActionButton from '$components/Button/ActionButton.svelte';
import { Icon, type IconType } from '$components/Icon';
import { Spinner } from '$components/Spinner';
import { connectedSourceChain } from '$stores/network';
import type { BridgeTransaction } from '$libs/bridge';
import { theme } from '$stores/theme';
import { TWO_STEP_STATE } from '../types';
Expand All @@ -16,7 +18,11 @@
export let claiming = false;
export let proveOrClaimStep: TWO_STEP_STATE;
export let proveOrClaimStep: TWO_STEP_STATE | null;
export let bridgeTx: BridgeTransaction;
export let txHash: Hash;
const dispatch = createEventDispatcher();
Expand All @@ -33,13 +39,20 @@
};
const getSuccessDescription = () => {
if (!txHash) return;
if (proveOrClaimStep === TWO_STEP_STATE.PROVE) {
return $t('bridge.step.confirm.success.prove_description');
}
const explorer = chainConfig[Number(bridgeTx.destChainId)]?.blockExplorers?.default.url;
const url = `${explorer}/tx/${txHash}`;
return $t('transactions.actions.claim.success.message', { values: { network: $connectedSourceChain.name } });
successDescription = $t('transactions.actions.claim.success.message', { values: { url } });
};
$: if (txHash && claimingDone) {
getSuccessDescription();
}
$: claimOrProveActionButton =
proveOrClaimStep === TWO_STEP_STATE.CLAIM
? $t('transactions.claim.steps.confirm.claim_button')
Expand All @@ -59,7 +72,7 @@
$: successIcon = `success-${$theme}` as IconType;
$: statusTitle = getSuccessTitle();
$: statusDescription = getSuccessDescription();
let successDescription = '';
$: claimDisabled = !canClaim || claiming;
</script>
Expand All @@ -74,7 +87,7 @@
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
<h1>{@html statusTitle}</h1>
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
<span class="">{@html statusDescription}</span>
<span class="">{@html successDescription}</span>
</div>
{:else if claiming}
<Spinner class="!w-[160px] !h-[160px] text-primary-brand" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,61 +1,103 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import { t } from 'svelte-i18n';
import type { Hash } from 'viem';
import { chainConfig } from '$chainConfig';
import { CloseButton } from '$components/Button';
import { infoToast, successToast } from '$components/NotificationToast/NotificationToast.svelte';
import { OnAccount } from '$components/OnAccount';
import { DialogStep, DialogStepper } from '$components/Transactions/Dialogs/Stepper';
import type { BridgeTransaction } from '$libs/bridge';
import { closeOnEscapeOrOutsideClick } from '$libs/customActions';
import { getLogger } from '$libs/util/logger';
import { uid } from '$libs/util/uid';
import { pendingTransactions } from '$stores/pendingTransactions';
import Claim from '../Claim.svelte';
import ClaimConfirmStep from '../ClaimDialog/ClaimSteps/ClaimConfirmStep.svelte';
import ClaimReviewStep from '../ClaimDialog/ClaimSteps/ClaimReviewStep.svelte';
import { TWO_STEP_STATE } from '../ClaimDialog/types';
import RetryStepNavigation from './RetryStepNavigation.svelte';
import RetryOptionStep from './RetrySteps/RetryOptionStep.svelte';
import { selectedRetryMethod } from './state';
import { INITIAL_STEP, RETRY_OPTION, RetrySteps } from './types';
export let dialogOpen = false;
export let item: BridgeTransaction;
export let bridgeTx: BridgeTransaction;
export let loading = false;
// export let loading = false;
const log = getLogger('RetryDialog');
const dispatch = createEventDispatcher();
const dialogId = `dialog-${uid()}`;
export let activeStep: RetrySteps = RetrySteps.SELECT;
let canContinue = false;
let retrying: boolean;
let retryDone = false;
let ClaimComponent: Claim;
let txHash: Hash;
const handleRetryError = () => {
retrying = false;
};
const handleAccountChange = () => {
reset();
};
const reset = () => {
activeStep = INITIAL_STEP;
$selectedRetryMethod = RETRY_OPTION.CONTINUE;
retryDone = false;
};
const closeDialog = () => {
dialogOpen = false;
reset();
};
const enum ClaimSteps {
INFO,
REVIEW,
CONFIRM,
}
export let activeStep: ClaimSteps = ClaimSteps.INFO;
let nextStepButtonText: string;
// const getStepText = () => {
// if (activeStep === ClaimSteps.INFO) {
// return $t('common.confirm');
// }
// if (activeStep === ClaimSteps.REVIEW) {
// return $t('common.ok');
// } else {
// return $t('common.continue');
// }
// };
const handleNextStep = () => {
if (activeStep === ClaimSteps.INFO) {
activeStep = ClaimSteps.REVIEW;
} else if (activeStep === ClaimSteps.REVIEW) {
activeStep = ClaimSteps.CONFIRM;
} else if (activeStep === ClaimSteps.CONFIRM) {
activeStep = ClaimSteps.INFO;
}
export const handleClaimClick = async () => {
retrying = true;
await ClaimComponent.claim();
};
const handlePreviousStep = () => {
if (activeStep === ClaimSteps.REVIEW) {
activeStep = ClaimSteps.INFO;
} else if (activeStep === ClaimSteps.CONFIRM) {
activeStep = ClaimSteps.REVIEW;
}
const handleRetryTxSent = async (event: CustomEvent<{ txHash: Hash }>) => {
const { txHash: transactionHash } = event.detail;
txHash = transactionHash;
log('handle claim tx sent', txHash);
retrying = true;
const explorer = chainConfig[Number(bridgeTx.destChainId)]?.blockExplorers?.default.url;
log('explorer', explorer);
infoToast({
title: $t('transactions.actions.claim.tx.title'),
message: $t('transactions.actions.claim.tx.message', {
values: {
token: bridgeTx.symbol,
url: `${explorer}/tx/${txHash}`,
},
}),
});
await pendingTransactions.add(txHash, Number(bridgeTx.destChainId));
retryDone = true;
dispatch('retryDone');
successToast({
title: $t('transactions.actions.claim.success.title'),
message: $t('transactions.actions.claim.tx.message', {
values: {
url: `${explorer}/tx/${txHash}`,
},
}),
});
};
</script>

Expand All @@ -67,30 +109,52 @@
<div class="modal-box relative px-6 py-[35px] w-full bg-neutral-background absolute">
<CloseButton onClick={closeDialog} />
<div class="w-full">
<h3 class="title-body-bold mb-7">{$t('token_dropdown.label')}</h3>
{item}
<DialogStepper on:click={() => handlePreviousStep()}>
<DialogStep stepIndex={ClaimSteps.INFO} currentStepIndex={activeStep} isActive={activeStep === ClaimSteps.INFO}
>{$t('bridge.step.import.title')}</DialogStep>
<h3 class="title-body-bold mb-7">{$t('transactions.retry.steps.title')}</h3>
<DialogStepper>
<DialogStep
stepIndex={ClaimSteps.REVIEW}
stepIndex={RetrySteps.SELECT}
currentStepIndex={activeStep}
isActive={activeStep === ClaimSteps.REVIEW}>{$t('bridge.step.review.title')}</DialogStep>
isActive={activeStep === RetrySteps.SELECT}>{$t('transactions.retry.steps.select.title')}</DialogStep>
<DialogStep
stepIndex={ClaimSteps.CONFIRM}
stepIndex={RetrySteps.REVIEW}
currentStepIndex={activeStep}
isActive={activeStep === ClaimSteps.CONFIRM}>{$t('bridge.step.confirm.title')}</DialogStep>
isActive={activeStep === RetrySteps.REVIEW}>{$t('common.review')}</DialogStep>
<DialogStep
stepIndex={RetrySteps.CONFIRM}
currentStepIndex={activeStep}
isActive={activeStep === RetrySteps.CONFIRM}>{$t('common.confirm')}</DialogStep>
</DialogStepper>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. A inventore, beatae aliquid quidem consectetur fuga?
Inventore ab dolorum reprehenderit possimus quidem voluptatem, rem repellat, laudantium fugit doloribus
aspernatur esse perferendis!
</p>
<div class="f-col text-left">
<button on:click={handleNextStep} class="btn btn-primary mt-5">{nextStepButtonText}</button>
<button on:click={handlePreviousStep} class="link mt-5 ml-3">{$t('common.back')}</button>

{#if activeStep === RetrySteps.SELECT}
<RetryOptionStep bind:canContinue />
{:else if activeStep === RetrySteps.REVIEW}
<ClaimReviewStep bind:tx={bridgeTx} />
{:else if activeStep === RetrySteps.CONFIRM}
<ClaimConfirmStep
{bridgeTx}
bind:txHash
on:claim={handleClaimClick}
bind:claiming={retrying}
bind:canClaim={canContinue}
bind:claimingDone={retryDone}
proveOrClaimStep={TWO_STEP_STATE.CLAIM} />
{/if}
<div class="f-col text-left self-end h-full w-full">
<div class="f-col gap-4 mt-[20px]">
<RetryStepNavigation
bind:activeStep
bind:canContinue
bind:loading
bind:retrying
on:closeDialog={closeDialog}
bind:retryDone />
</div>
</div>
</div>
</div>
<button class="overlay-backdrop" data-modal-uuid={dialogId} />
</dialog>

<Claim bind:bridgeTx bind:this={ClaimComponent} on:error={handleRetryError} on:claimingTxSent={handleRetryTxSent} />

<OnAccount change={handleAccountChange} />
Loading

0 comments on commit 3beba21

Please sign in to comment.