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): re-add mobile details #17016

Merged
merged 5 commits into from
May 16, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@
let canonicalAddress: Address | null;
let canonicalChain: number | null;

$: if (token && !fetchingAddress && !canonicalAddress && !bridgedAddress) {
fetchTokenAddresses();
}
const forwardEvent = (e: CustomEvent) => {
dispatch(e.type, e.detail);
};

const fetchTokenAddresses = async () => {
if (!token) return;
Expand Down Expand Up @@ -85,6 +85,9 @@
fetchingAddress = false;
};

$: if (token && !fetchingAddress && !canonicalAddress && !bridgedAddress) {
fetchTokenAddresses();
}
$: imageUrl = token?.metadata?.image || placeholderUrl;

$: isERC721 = selectedItem?.tokenType === TokenType.ERC721;
Expand Down Expand Up @@ -127,7 +130,11 @@
</div>
</h4>
<div class="f-items-center space-x-1">
<Status bridgeTx={selectedItem} on:insufficientFunds={handleInsufficientFunds} />
<Status
bridgeTxStatus={selectedItem.status}
bridgeTx={selectedItem}
on:openModal={forwardEvent}
on:insufficientFunds={handleInsufficientFunds} />
</div>
</li>

Expand Down
39 changes: 10 additions & 29 deletions packages/bridge-ui/src/components/Transactions/Status/Status.svelte
Original file line number Diff line number Diff line change
@@ -1,45 +1,33 @@
<script lang="ts">
import { onDestroy, onMount } from 'svelte';
import { createEventDispatcher, onDestroy, onMount } from 'svelte';
import { t } from 'svelte-i18n';

import { ClaimDialog, ReleaseDialog, RetryDialog } from '$components/Dialogs';
import { Spinner } from '$components/Spinner';
import { StatusDot } from '$components/StatusDot';
import { type BridgeTransaction, MessageStatus } from '$libs/bridge';
import { getMessageStatusForMsgHash } from '$libs/bridge/getMessageStatusForMsgHash';
import { isTransactionProcessable } from '$libs/bridge/isTransactionProcessable';
import { BridgePausedError } from '$libs/error';
import { PollingEvent, startPolling } from '$libs/polling/messageStatusPoller';
import type { NFT } from '$libs/token';
import { isBridgePaused } from '$libs/util/checkForPausedContracts';
import { account } from '$stores/account';
import { connectedSourceChain } from '$stores/network';

const dispatch = createEventDispatcher();

export let bridgeTx: BridgeTransaction;
export let nft: NFT | null = null;

let polling: ReturnType<typeof startPolling>;

// UI state
let isProcessable = false; // bridge tx state to be processed: claimed/retried/released
let bridgeTxStatus: Maybe<MessageStatus>;
export let bridgeTxStatus: Maybe<MessageStatus>;

let loading = false;

function onProcessable(isTxProcessable: boolean) {
isProcessable = isTxProcessable;
}

async function claimingDone() {
// Keeping model and UI in sync
bridgeTx.msgStatus = await getMessageStatusForMsgHash({
msgHash: bridgeTx.msgHash,
srcChainId: Number(bridgeTx.srcChainId),
destChainId: Number(bridgeTx.destChainId),
});
bridgeTxStatus = bridgeTx.msgStatus;
}

function onStatusChange(status: MessageStatus) {
// Keeping model and UI in sync
bridgeTxStatus = bridgeTx.msgStatus = status;
Expand All @@ -50,15 +38,17 @@
if (paused) throw new BridgePausedError('Bridge is paused');
});
if (!$connectedSourceChain || !$account?.address) return;
retryModalOpen = true;
// retryModalOpen = true;
dispatch('openModal', 'retry');
}

async function handleReleaseClick() {
isBridgePaused().then((paused) => {
if (paused) throw new BridgePausedError('Bridge is paused');
});
if (!$connectedSourceChain || !$account?.address) return;
releaseModalOpen = true;
// releaseModalOpen = true;
dispatch('openModal', 'release');
}

async function handleClaimClick() {
Expand All @@ -67,7 +57,8 @@
});
if (!$connectedSourceChain || !$account?.address) return;

claimModalOpen = true;
// claimModalOpen = true;
dispatch('openModal', 'claim');
}

async function release() {
Expand All @@ -78,10 +69,6 @@
// TODO: implement release handling
}

$: claimModalOpen = false;
$: retryModalOpen = false;
$: releaseModalOpen = false;

onMount(async () => {
if (bridgeTx && $account?.address) {
bridgeTxStatus = bridgeTx.msgStatus;
Expand Down Expand Up @@ -143,9 +130,3 @@
<span>{$t('transactions.status.error.name')}</span>
{/if}
</div>

<RetryDialog {bridgeTx} bind:dialogOpen={retryModalOpen} />

<ReleaseDialog {bridgeTx} bind:dialogOpen={releaseModalOpen} />

<ClaimDialog {bridgeTx} bind:loading bind:dialogOpen={claimModalOpen} {nft} on:claimingDone={() => claimingDone()} />
86 changes: 80 additions & 6 deletions packages/bridge-ui/src/components/Transactions/Transaction.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@

import { chainConfig } from '$chainConfig';
import { DesktopOrLarger } from '$components/DesktopOrLarger';
import { ClaimDialog, ReleaseDialog, RetryDialog } from '$components/Dialogs';
import { Icon } from '$components/Icon';
import { LoadingText } from '$components/LoadingText';
import NftInfoDialog from '$components/NFTs/NFTInfoDialog.svelte';
import Spinner from '$components/Spinner/Spinner.svelte';
import type { BridgeTransaction } from '$libs/bridge';
import { type BridgeTransaction, MessageStatus } from '$libs/bridge';
import { getMessageStatusForMsgHash } from '$libs/bridge/getMessageStatusForMsgHash';
import { getChainName } from '$libs/chain';
import { type NFT, TokenType } from '$libs/token';
import { fetchNFTImageUrl } from '$libs/token/fetchNFTImageUrl';
Expand All @@ -17,6 +19,7 @@

import ChainSymbolName from './ChainSymbolName.svelte';
import InsufficientFunds from './InsufficientFunds.svelte';
import MobileDetailsDialog from './MobileDetailsDialog.svelte';
import { Status } from './Status';

export let item: BridgeTransaction;
Expand All @@ -26,6 +29,9 @@
let insufficientModal = false;
let nftInfoOpen = false;
let isDesktopOrLarger = false;
let detailsOpen = false;

let bridgeTxStatus: Maybe<MessageStatus>;

let attrs = isDesktopOrLarger ? {} : { role: 'button' };

Expand All @@ -35,10 +41,30 @@
nftInfoOpen = true;
};

const openDetails = () => {
if (!isDesktopOrLarger && !interactiveDialogsOpen) {
detailsOpen = true;
}
};

const closeDetails = () => {
detailsOpen = false;
};

const handleInsufficientFunds = () => {
insufficientModal = true;
};

const handleOpenModal = (event: CustomEvent) => {
if (event.detail === 'retry') {
retryModalOpen = true;
} else if (event.detail === 'release') {
releaseModalOpen = true;
} else if (event.detail === 'claim') {
claimModalOpen = true;
}
};

async function analyzeTransactionInput(): Promise<void> {
loading = true;
try {
Expand All @@ -54,6 +80,16 @@
loading = false;
}

async function claimingDone() {
// Keeping model and UI in sync
item.msgStatus = await getMessageStatusForMsgHash({
msgHash: item.msgHash,
srcChainId: Number(item.srcChainId),
destChainId: Number(item.destChainId),
});
bridgeTxStatus = item.msgStatus;
}

$: {
if (item.tokenType === TokenType.ERC721 || item.tokenType === TokenType.ERC1155) {
// for NFTs we need to fetch more information about the transaction
Expand All @@ -66,6 +102,12 @@
$: itemAmountDisplay = item.tokenType === TokenType.ERC721 ? '---' : item.amount;

$: isNFT = [TokenType.ERC1155, TokenType.ERC721].includes(item.tokenType);

$: claimModalOpen = false;
$: retryModalOpen = false;
$: releaseModalOpen = false;

$: interactiveDialogsOpen = claimModalOpen || retryModalOpen || releaseModalOpen;
</script>

{#if isNFT}
Expand Down Expand Up @@ -108,7 +150,8 @@
{itemAmountDisplay}
</div>
{:else}
<div class="flex text-primary-content w-full justify-content-left">
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div on:click={openDetails} {...attrs} class="flex text-primary-content w-full justify-content-left">
{#if loading}
<div class="rounded-[10px] w-[50px] h-[50px] bg-neutral flex items-center justify-center">
<Spinner />
Expand All @@ -128,7 +171,7 @@
<LoadingText mask="&nbsp;" class="min-w-[50px] max-w-[50px] h-3" />
</div>
{:else}
<div class="f-col" {...attrs} tabindex="0">
<div class="f-col" tabindex="0">
<div class="f-row font-bold">
{truncateString(getChainName(Number(item.srcChainId)), 8)}
<i role="img" aria-label="arrow to" class="mx-auto px-2">
Expand All @@ -142,7 +185,11 @@
</div>
{/if}
<div class="flex md:w-2/12 py-2 flex flex-col justify-center text-center" {...attrs} tabindex="0">
<Status bridgeTx={item} nft={token} on:insufficientFunds={handleInsufficientFunds} />
<Status
bridgeTx={item}
bind:bridgeTxStatus
on:openModal={handleOpenModal}
on:insufficientFunds={handleInsufficientFunds} />
</div>
<div class="hidden md:flex grow py-2 flex flex-col justify-center">
<a
Expand All @@ -155,7 +202,11 @@
</div>
</div>
{:else}
<div {...attrs} class="flex text-primary-content md:h-[80px] h-[45px] w-full my-[10px] md:my-[0px]">
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
on:click={openDetails}
{...attrs}
class="flex text-primary-content md:h-[80px] h-[45px] w-full my-[10px] md:my-[0px]">
{#if isDesktopOrLarger}
<div class="w-1/5 py-2 flex flex-row">
<ChainSymbolName chainId={item.srcChainId} />
Expand Down Expand Up @@ -194,7 +245,11 @@
{/if}

<div class="md:w-1/5 py-2 flex flex-col justify-center">
<Status bridgeTx={item} on:insufficientFunds={handleInsufficientFunds} />
<Status
bridgeTx={item}
bind:bridgeTxStatus
on:openModal={handleOpenModal}
on:insufficientFunds={handleInsufficientFunds} />
</div>
<div class="hidden md:flex w-1/5 py-2 flex flex-col justify-center">
<a
Expand All @@ -213,3 +268,22 @@
<NftInfoDialog nft={token} bind:modalOpen={nftInfoOpen} viewOnly />

<InsufficientFunds bind:modalOpen={insufficientModal} />

<MobileDetailsDialog
{token}
{closeDetails}
{detailsOpen}
selectedItem={item}
on:insufficientFunds={handleInsufficientFunds}
on:openModal={handleOpenModal} />

<RetryDialog bridgeTx={item} bind:dialogOpen={retryModalOpen} />

<ReleaseDialog bridgeTx={item} bind:dialogOpen={releaseModalOpen} />

<ClaimDialog
bridgeTx={item}
bind:loading
bind:dialogOpen={claimModalOpen}
nft={token}
on:claimingDone={() => claimingDone()} />