From c22b1b9ac11ca8f066ce05d10843bd364c582bfc Mon Sep 17 00:00:00 2001 From: Korbinian Date: Sat, 28 Oct 2023 06:23:54 +0200 Subject: [PATCH] chore(bridge-ui-v2): review step refinement (#15037) Signed-off-by: dependabot[bot] Co-authored-by: xiaodino Co-authored-by: Roger <50648015+RogerLamTd@users.noreply.github.com> Co-authored-by: Kenk Co-authored-by: dave <13951458+d1onys1us@users.noreply.github.com> Co-authored-by: FINE <101636126+finedao@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../src/components/Bridge/NFTBridge.svelte | 51 ++-- .../Bridge/NFTBridgeSteps/ImportStep.svelte | 1 + .../NFTBridgeSteps/RecipientStep.svelte | 18 ++ .../Bridge/NFTBridgeSteps/ReviewStep.svelte | 115 ++++--- .../components/Bridge/NFTBridgeSteps/index.ts | 1 + .../Bridge/ProcessingFee/ProcessingFee.svelte | 289 ++++++++++-------- .../src/components/Bridge/Recipient.svelte | 127 ++++---- .../src/components/Bridge/state.ts | 2 + .../src/components/Bridge/types.ts | 1 + .../components/NFTs/NFTCards/NFTCard.svelte | 6 +- .../NFTs/NFTCards/NFTCardGrid.svelte | 58 ++-- .../src/components/NFTs/NFTDisplay.svelte | 9 +- .../src/components/NFTs/NFTInfoDialog.svelte | 16 +- .../components/NFTs/NFTList/NFTList.svelte | 12 +- .../NFTs/NFTList/NFTListItem.svelte | 44 ++- packages/bridge-ui-v2/src/i18n/en.json | 22 +- .../src/libs/bridge/getBridgeArgs.ts | 14 +- .../src/libs/token/getCrossChainAddress.ts | 17 +- 18 files changed, 477 insertions(+), 326 deletions(-) create mode 100644 packages/bridge-ui-v2/src/components/Bridge/NFTBridgeSteps/RecipientStep.svelte diff --git a/packages/bridge-ui-v2/src/components/Bridge/NFTBridge.svelte b/packages/bridge-ui-v2/src/components/Bridge/NFTBridge.svelte index 05f5285f63..c093ccec8d 100644 --- a/packages/bridge-ui-v2/src/components/Bridge/NFTBridge.svelte +++ b/packages/bridge-ui-v2/src/components/Bridge/NFTBridge.svelte @@ -35,9 +35,9 @@ import type Amount from './Amount.svelte'; import type IdInput from './IDInput/IDInput.svelte'; import ImportStep from './NFTBridgeSteps/ImportStep.svelte'; + import RecipientStep from './NFTBridgeSteps/RecipientStep.svelte'; import ReviewStep from './NFTBridgeSteps/ReviewStep.svelte'; import type { ProcessingFee } from './ProcessingFee'; - import type Recipient from './Recipient.svelte'; import { activeBridge, bridgeService, @@ -50,7 +50,7 @@ import { NFTSteps } from './types'; let amountComponent: Amount; - let recipientComponent: Recipient; + let recipientStepComponent: RecipientStep; let processingFeeComponent: ProcessingFee; let actionsComponent: Actions; let importMethod: 'scan' | 'manual' = 'scan'; @@ -181,7 +181,7 @@ const tokenIds = nftIdArray.length > 0 ? nftIdArray.map((num) => BigInt(num)) : selectedNFT.map((nft) => BigInt(nft.tokenId)); - const bridgeArgs = await getBridgeArgs($selectedToken, $enteredAmount, commonArgs, selectedNFT, nftIdArray); + const bridgeArgs = await getBridgeArgs($selectedToken, $enteredAmount, commonArgs, nftIdArray); const args = { ...bridgeArgs, tokenIds }; @@ -242,9 +242,9 @@ const resetForm = () => { //we check if these are still mounted, as the user might have left the page if (amountComponent) amountComponent.clearAmount(); - if (recipientComponent) recipientComponent.clearRecipient(); if (processingFeeComponent) processingFeeComponent.resetProcessingFee(); if (addressInputComponent) addressInputComponent.clearAddress(); + if (recipientStepComponent) recipientStepComponent.reset(); // Update balance after bridging if (amountComponent) amountComponent.updateBalance(); @@ -335,6 +335,10 @@ }); }; + const handleTransactionDetailsClick = () => { + activeStep = NFTSteps.RECIPIENT; + }; + // Whenever the user switches bridge types, we should reset the forms $: $activeBridge && (resetForm(), (activeStep = NFTSteps.IMPORT)); @@ -345,6 +349,7 @@ nftStepDescription = $t(`bridge.description.nft.${stepKey}`); nextStepButtonText = getStepText(); } + onDestroy(() => { resetForm(); }); @@ -353,12 +358,13 @@
{$t('bridge.title.nft.import')} + >{$t('bridge.nft.step.import.title')} {$t('bridge.title.nft.review')} + >{$t('bridge.nft.step.review.title')} {$t('bridge.title.nft.confirm')} + >{$t('bridge.nft.step.confirm.title')} +
@@ -368,32 +374,29 @@ bind:canProceed bind:nftIdArray bind:contractAddress - {foundNFTs} + bind:foundNFTs bind:scanned bind:validating={validatingImport} /> {:else if activeStep === NFTSteps.REVIEW} - + {:else if activeStep === NFTSteps.CONFIRM}
+ {:else if activeStep === NFTSteps.RECIPIENT} + {/if} - {#if activeStep !== NFTSteps.IMPORT} - - {/if} {#if activeStep === NFTSteps.REVIEW} -
-
+
+
{:else if activeStep === NFTSteps.IMPORT} {#if importMethod === 'manual'} @@ -426,6 +429,18 @@
{/if} + {:else if activeStep === NFTSteps.RECIPIENT} +
+ + + +
{/if}
diff --git a/packages/bridge-ui-v2/src/components/Bridge/NFTBridgeSteps/ImportStep.svelte b/packages/bridge-ui-v2/src/components/Bridge/NFTBridgeSteps/ImportStep.svelte index 6cda53093d..2f5cf29f1c 100644 --- a/packages/bridge-ui-v2/src/components/Bridge/NFTBridgeSteps/ImportStep.svelte +++ b/packages/bridge-ui-v2/src/components/Bridge/NFTBridgeSteps/ImportStep.svelte @@ -217,6 +217,7 @@ + {#if importMethod === 'manual'}
+ import { ProcessingFee } from '../ProcessingFee'; + import Recipient from '../Recipient.svelte'; + + let recipientComponent: Recipient; + let processingFeeComponent: ProcessingFee; + export let hasEnoughEth: boolean = false; + + export const reset = () => { + recipientComponent.clearRecipient(); + processingFeeComponent.resetProcessingFee(); + }; + + + + + +
diff --git a/packages/bridge-ui-v2/src/components/Bridge/NFTBridgeSteps/ReviewStep.svelte b/packages/bridge-ui-v2/src/components/Bridge/NFTBridgeSteps/ReviewStep.svelte index 19f85e63c8..f30db8322e 100644 --- a/packages/bridge-ui-v2/src/components/Bridge/NFTBridgeSteps/ReviewStep.svelte +++ b/packages/bridge-ui-v2/src/components/Bridge/NFTBridgeSteps/ReviewStep.svelte @@ -1,18 +1,22 @@
-
{$t('common.destination')}
-
+
{$t('bridge.nft.step.review.transfer_details')}
-
-
{$t('common.contract_address')}
-
- +
+
+
{$t('common.from')}
+
{$network?.name}
+
+
+
{$t('common.to')}
+
{$destinationChain?.name}
-
-
-
{$t('inputs.token_id_input.label')}
-
-
    - {#each nftsToDisplay as nft} -
  • {nft.tokenId}
  • - {/each} -
+
+
{$t('common.contract_address')}
+
+ +
-
-
-
- -
- - +
+
{$t('inputs.token_id_input.label')}
+
+
    + {#each nftsToDisplay as nft} +
  • {nft.tokenId}
  • + {/each} +
+
+
+ +
+
{$t('common.amount')}
+ {$enteredAmount} +
+
-
-
+
{$t('bridge.nft.step.review.your_tokens')} @@ -101,3 +114,19 @@ NFT List or Card View
+ +
+ + +
+
+
{$t('bridge.nft.step.review.recipient_details')}
+ +
+ + +
+ +
diff --git a/packages/bridge-ui-v2/src/components/Bridge/NFTBridgeSteps/index.ts b/packages/bridge-ui-v2/src/components/Bridge/NFTBridgeSteps/index.ts index 6656ce9828..36f093a3d9 100644 --- a/packages/bridge-ui-v2/src/components/Bridge/NFTBridgeSteps/index.ts +++ b/packages/bridge-ui-v2/src/components/Bridge/NFTBridgeSteps/index.ts @@ -1,2 +1,3 @@ export { default as ImportStep } from './ImportStep.svelte'; +export { default as RecipientStep } from './RecipientStep.svelte'; export { default as ReviewStep } from './ReviewStep.svelte'; diff --git a/packages/bridge-ui-v2/src/components/Bridge/ProcessingFee/ProcessingFee.svelte b/packages/bridge-ui-v2/src/components/Bridge/ProcessingFee/ProcessingFee.svelte index 2503e5bf48..a2a811167b 100644 --- a/packages/bridge-ui-v2/src/components/Bridge/ProcessingFee/ProcessingFee.svelte +++ b/packages/bridge-ui-v2/src/components/Bridge/ProcessingFee/ProcessingFee.svelte @@ -13,19 +13,20 @@ import { parseToWei } from '$libs/util/parseToWei'; import { uid } from '$libs/util/uid'; - import { processingFee } from '../state'; + import { processingFee, processingFeeMethod } from '../state'; import NoneOption from './NoneOption.svelte'; import RecommendedFee from './RecommendedFee.svelte'; + export let small = false; + export let hasEnoughEth = false; + let dialogId = `dialog-${uid()}`; - let selectedFeeMethod = ProcessingFeeMethod.RECOMMENDED; let prevOptionSelected = ProcessingFeeMethod.RECOMMENDED; let recommendedAmount = BigInt(0); let calculatingRecommendedAmount = false; let errorCalculatingRecommendedAmount = false; - let hasEnoughEth = false; let calculatingEnoughEth = false; let errorCalculatingEnoughEth = false; @@ -35,14 +36,14 @@ // Public API export function resetProcessingFee() { inputBox?.clear(); - selectedFeeMethod = ProcessingFeeMethod.RECOMMENDED; + $processingFeeMethod = ProcessingFeeMethod.RECOMMENDED; } function closeModal() { // Let's check if we are closing with CUSTOM method selected and zero amount entered - if (selectedFeeMethod === ProcessingFeeMethod.CUSTOM && $processingFee === BigInt(0)) { + if ($processingFeeMethod === ProcessingFeeMethod.CUSTOM && $processingFee === BigInt(0)) { // If so, let's switch to RECOMMENDED method - selectedFeeMethod = ProcessingFeeMethod.RECOMMENDED; + $processingFeeMethod = ProcessingFeeMethod.RECOMMENDED; } removeEscKeyListener(); modalOpen = false; @@ -51,14 +52,14 @@ function openModal() { // Keep track of the selected method before opening the modal // so if we cancel we can go back to the previous method - prevOptionSelected = selectedFeeMethod; + prevOptionSelected = $processingFeeMethod; addEscKeyListener(); modalOpen = true; } function cancelModal() { inputBox?.clear(); - selectedFeeMethod = prevOptionSelected; + $processingFeeMethod = prevOptionSelected; closeModal(); } @@ -67,7 +68,7 @@ } function inputProcessFee(event: Event) { - if (selectedFeeMethod !== ProcessingFeeMethod.CUSTOM) return; + if ($processingFeeMethod !== ProcessingFeeMethod.CUSTOM) return; const { value } = event.target as HTMLInputElement; $processingFee = parseToWei(value); @@ -117,157 +118,179 @@ function unselectNoneIfNotEnoughETH(method: ProcessingFeeMethod, enoughEth: boolean) { if (method === ProcessingFeeMethod.NONE && !enoughEth) { - selectedFeeMethod = ProcessingFeeMethod.RECOMMENDED; + $processingFeeMethod = ProcessingFeeMethod.RECOMMENDED; // We need to manually trigger this update because we are already in an update // cicle, meaning the change above will not start a new one. This is how Svelte // works, batching all the changes and kicking off an update cicle. This could // also prevent infinite loops. It's safe though to call this function because // we're not changing state that could potentially end up in such situation. - updateProcessingFee(selectedFeeMethod, recommendedAmount); + updateProcessingFee($processingFeeMethod, recommendedAmount); } } - $: updateProcessingFee(selectedFeeMethod, recommendedAmount); - - $: unselectNoneIfNotEnoughETH(selectedFeeMethod, hasEnoughEth); + $: { + updateProcessingFee($processingFeeMethod, recommendedAmount); + } + $: unselectNoneIfNotEnoughETH($processingFeeMethod, hasEnoughEth); -
-
-
- {$t('processing_fee.title')} - -

{$t('processing_fee.tooltip_title')}

- {$t('processing_fee.tooltip')} -
+{#if small} +
+
+ {$t('processing_fee.title')} + + {#if calculatingRecommendedAmount} + ETH + {:else if errorCalculatingRecommendedAmount} + {$t('processing_fee.recommended.error')} + {:else} + {formatEther($processingFee ?? BigInt(0))} ETH {#if $processingFee !== recommendedAmount} + | Customized + {/if} + {/if} +
-
+{:else} +
+
+
+ {$t('processing_fee.title')} + +

{$t('processing_fee.tooltip_title')}

+ {$t('processing_fee.tooltip')} +
+
+ +
- - {#if calculatingRecommendedAmount} - ETH - {:else if errorCalculatingRecommendedAmount} - {$t('processing_fee.recommended.error')} - {:else} - {formatEther($processingFee ?? BigInt(0))} ETH - {/if} - - - - - -
+ +
+{/if} diff --git a/packages/bridge-ui-v2/src/components/Bridge/Recipient.svelte b/packages/bridge-ui-v2/src/components/Bridge/Recipient.svelte index ad27f0cf7e..27ea58ded8 100644 --- a/packages/bridge-ui-v2/src/components/Bridge/Recipient.svelte +++ b/packages/bridge-ui-v2/src/components/Bridge/Recipient.svelte @@ -1,5 +1,4 @@
-
-
- {$t('recipient.title')} - -

{$t('recipient.tooltip_title')}

- {$t('recipient.tooltip')} -
+ {#if small} +
+ {$t('recipient.title')} + {#if displayedRecipient} + {shortenAddress(displayedRecipient, 8, 10)} + {#if displayedRecipient !== $account?.address} + | Customized + {/if} + {:else} + {$t('recipient.placeholder')} + {/if} +
+ {:else} +
+
+ {$t('recipient.title')} + +

{$t('recipient.tooltip_title')}

+ {$t('recipient.tooltip')} +
+
+
- -
- - - {#if displayedRecipient} - {shortenAddress(displayedRecipient, 15, 13)} - {$recipientAddress !== $account?.address ? '' : '| Customized'} - {:else} - {$t('recipient.placeholder')} - {/if} - - - - + + {/if}
diff --git a/packages/bridge-ui-v2/src/components/Bridge/state.ts b/packages/bridge-ui-v2/src/components/Bridge/state.ts index ef36dcc4ec..0f7f288a84 100644 --- a/packages/bridge-ui-v2/src/components/Bridge/state.ts +++ b/packages/bridge-ui-v2/src/components/Bridge/state.ts @@ -3,6 +3,7 @@ import { derived, writable } from 'svelte/store'; import { bridges } from '$libs/bridge'; import { chains } from '$libs/chain'; +import { ProcessingFeeMethod } from '$libs/fee'; import type { NFT, Token } from '$libs/token'; import { type BridgeType, BridgeTypes } from './types'; @@ -24,6 +25,7 @@ export const enteredAmount = writable(BigInt(0)); export const destNetwork = writable>(null); export const destOptions = writable(chains); export const processingFee = writable(BigInt(0)); +export const processingFeeMethod = writable(ProcessingFeeMethod.RECOMMENDED); export const recipientAddress = writable>(null); // Loading state diff --git a/packages/bridge-ui-v2/src/components/Bridge/types.ts b/packages/bridge-ui-v2/src/components/Bridge/types.ts index ff01ce4e5b..a91f1ed935 100644 --- a/packages/bridge-ui-v2/src/components/Bridge/types.ts +++ b/packages/bridge-ui-v2/src/components/Bridge/types.ts @@ -6,6 +6,7 @@ export enum BridgeTypes { export enum NFTSteps { IMPORT, REVIEW, + RECIPIENT, CONFIRM, } diff --git a/packages/bridge-ui-v2/src/components/NFTs/NFTCards/NFTCard.svelte b/packages/bridge-ui-v2/src/components/NFTs/NFTCards/NFTCard.svelte index 71724689d1..179e8f7cfb 100644 --- a/packages/bridge-ui-v2/src/components/NFTs/NFTCards/NFTCard.svelte +++ b/packages/bridge-ui-v2/src/components/NFTs/NFTCards/NFTCard.svelte @@ -45,12 +45,12 @@
{/if} -
- {nft.name} +
+ {nft.name}
{:else} - {nft.name} + {nft.name} {/if}