Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(bridge-ui): retry dialog #16536

Merged
merged 2 commits into from
Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading