Skip to content

Commit

Permalink
feat(bridge-ui-v2): switch chain (#14117)
Browse files Browse the repository at this point in the history
Co-authored-by: David <[email protected]>
Co-authored-by: dave | d1onys1us <[email protected]>
  • Loading branch information
3 people authored Jul 10, 2023
1 parent 2f4a0be commit d51161d
Show file tree
Hide file tree
Showing 29 changed files with 416 additions and 102 deletions.
1 change: 1 addition & 0 deletions packages/bridge-ui-v2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"@wagmi/core": "^1.3.6",
"@web3modal/ethereum": "^2.6.2",
"@web3modal/html": "^2.6.2",
"@zerodevx/svelte-toast": "^0.9.5",
"abitype": "^0.8.2",
"debug": "^4.3.4",
"svelte-i18n": "^3.6.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<script lang="ts">
import { t } from 'svelte-i18n';
import { successToast, warningToast } from '$components/NotificationToast';
import { account } from '$stores/account';
let prevAccount = $account;
// Listen to changes in the account state and notify the user
// when the account is connected or disconnected via toast
account.subscribe((_account) => {
if (_account?.isConnected) {
successToast($t('messages.account.connected'));
} else if (prevAccount && _account?.isDisconnected) {
// We check if there was previous account, if not
// the user just hit the app, and there is no need
// to show the message.
warningToast($t('messages.account.disconnected'));
}
prevAccount = _account;
});
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as AccountConnectionToast } from './AccountConnectionToast.svelte';
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
import { Card } from '$components/Card';
import { ChainSelector } from '$components/ChainSelector';
import { srcChain } from '$stores/network';
import ListWithDetailsView from './ListWithDetailsView.svelte';
import TableView from './TableView.svelte';
</script>

<Card class="md:min-w-[524px]" title={$t('activities.title')} text={$t('activities.subtitle')}>
<div class="space-y-[35px]">
<ChainSelector label={$t('chain_selector.currently_on')} />
<ChainSelector label={$t('chain_selector.currently_on')} value={$srcChain} />
<!-- Small size view -->
<div class="md:hidden">
<ListWithDetailsView />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
</script>

<div class="f-col space-y-2">
<div class="f-between-center text-secondary-content body-regular">
<label for={inputId}>{$t('amount_input.label')}</label>
<div>
<div class="f-between-center text-secondary-content">
<label class="body-regular" for={inputId}>{$t('amount_input.label')}</label>
<div class="body-small-regular">
<span>{$t('amount_input.balance')}:</span>
<span>399.92 ETH</span>
</div>
Expand Down
31 changes: 26 additions & 5 deletions packages/bridge-ui-v2/src/components/Bridge/Bridge.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script>
<script lang="ts">
import type { Chain } from '@wagmi/core';
import { t } from 'svelte-i18n';
import AmountInput from '$components/AmountInput';
Expand All @@ -9,27 +10,47 @@
import { ProcessingFee } from '$components/ProcessingFee';
import { RecipientInput } from '$components/RecipientInput';
import { TokenDropdown } from '$components/TokenDropdown';
import { web3modal } from '$libs/connect';
import { tokens } from '$libs/token';
import { destChain, srcChain } from '$stores/network';
function onSrcChainChange(chain: Chain) {
if (chain !== $srcChain) {
srcChain.set(chain);
// Let's not forget to update the default chain
// in web3modal. Unfortunately we have to maintain
// two states here due to the fact that the user
// can change the network from the UI.
web3modal.setDefaultChain(chain);
}
}
function onDestChainChange(chain: Chain) {
if (chain !== $destChain) {
destChain.set(chain);
}
}
</script>

<Card class="md:w-[524px]" title={$t('bridge.title')} text={$t('bridge.subtitle')}>
<div class="space-y-[35px]">
<div class="space-y-4">
<div class="space-y-2">
<ChainSelector label={$t('chain.from')} />
<ChainSelector label={$t('chain.from')} value={$srcChain} onChange={onSrcChainChange} />
<TokenDropdown {tokens} />
</div>

<AmountInput />

<div class="f-justify-center">
<button>
<Icon type="up-down-circle" size={36} />
<button class="f-center rounded-full bg-secondary-icon w-[30px] h-[30px]">
<Icon type="up-down" />
</button>
</div>

<div class="space-y-2">
<ChainSelector label={$t('chain.to')} />
<ChainSelector label={$t('chain.to')} value={$destChain} onChange={onDestChainChange} />
<RecipientInput />
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
<script lang="ts">
import type { Chain } from '@wagmi/core';
import type { Chain, GetNetworkResult } from '@wagmi/core';
import type { ComponentType } from 'svelte';
import { noop, onDestroy } from 'svelte/internal';
import { t } from 'svelte-i18n';
import { EthIcon, Icon, TaikoIcon } from '$components/Icon';
import { warningToast } from '$components/NotificationToast';
import { PUBLIC_L1_CHAIN_ID, PUBLIC_L2_CHAIN_ID } from '$env/static/public';
import { chains } from '$libs/chain';
import { uid } from '$libs/util/uid';
import { account } from '$stores/account';
// TODO: think about updating the state for the network here
export let label: string;
export let value: Maybe<GetNetworkResult['chain']> = null;
export let onChange: (chain: Chain) => void = noop;
let chainToIconMap: Record<string, ComponentType> = {
Expand All @@ -19,19 +24,27 @@
let buttonId = `button-${uid()}`;
let dialogId = `dialog-${uid()}`;
let selectedChain: Chain;
let modalOpen = false;
function closeModal() {
modalOpen = false;
}
function openModal() {
// We want to inform the user that they need to connect
// their wallet if they want to change the network
if (!$account.isConnected) {
warningToast($t('messages.account.required'));
return;
}
modalOpen = true;
}
function selectChain(chain: Chain) {
selectedChain = chain;
if (chain === value) return;
value = chain;
onChange?.(chain); // TODO: data binding? 🤔
closeModal();
}
Expand All @@ -56,23 +69,23 @@
aria-haspopup="dialog"
aria-controls={dialogId}
aria-expanded={modalOpen}
class="px-2 py-[6px] body-small-regular bg-neutral-background rounded-md min-w-[150px]"
class="px-2 py-[6px] body-small-regular bg-neutral-background rounded-md"
on:click={openModal}>
<div class="f-items-center space-x-2">
{#if !selectedChain}
<span>{$t('chain_selector.placeholder')}</span>
{#if !value}
<span>{$t('chain_selector.placeholder')}</span>
{/if}
{#if selectedChain}
<i role="img" aria-label={selectedChain.name}>
<svelte:component this={chainToIconMap[selectedChain.id]} size={20} />
{#if value}
<i role="img" aria-label={value.name}>
<svelte:component this={chainToIconMap[value.id]} size={20} />
</i>
<span>{selectedChain.name}</span>
<span>{value.name}</span>
{/if}
</div>
</button>
</div>

<dialog id={dialogId} class="modal" class:modal-open={modalOpen}>
<dialog id={dialogId} class="modal modal-bottom md:modal-middle" class:modal-open={modalOpen}>
<div class="modal-box relative px-6 py-[21px] bg-primary-base-background text-primary-base-content">
<button class="absolute right-6 top-[21px]" on:click={closeModal}>
<Icon type="x-close" fillClass="fill-secondary-icon" />
Expand All @@ -83,6 +96,8 @@
<li
role="menuitem"
tabindex="0"
class:opacity-50={chain === value}
aria-disabled={chain === value}
on:click={() => selectChain(chain)}
on:keydown={getChainKeydownHandler(chain)}>
<!-- TODO: agree on hover:bg color -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<script lang="ts">
import { onDestroy, onMount } from 'svelte';
import { noop } from 'svelte/internal';
import { t } from 'svelte-i18n';
import { Button } from '$components/Button';
import { Icon } from '$components/Icon';
import { Spinner } from '$components/Spinner';
import { web3modal } from '$libs/connect';
export let connected = false;
let web3modalOpen = false;
let unsubscribeWeb3Modal = noop;
function connectWallet() {
web3modal.openModal();
}
function onWeb3Modal(state: { open: boolean }) {
web3modalOpen = state.open;
}
onMount(() => {
unsubscribeWeb3Modal = web3modal.subscribeModal(onWeb3Modal);
});
onDestroy(unsubscribeWeb3Modal);
</script>

<!--
We are gonna make use of Web3Modal core button when we are connected,
which comes with interesting features out of the box.
https://docs.walletconnect.com/2.0/web/web3modal/html/wagmi/components
-->
{#if connected}
<w3m-core-button balance="show" />
{:else}
<!-- TODO: fixing the width for English. i18n? -->
<Button class="px-[20px] py-2 rounded-full w-[215px]" type="neutral" on:click={connectWallet}>
<span class="body-regular f-items-center space-x-2">
{#if web3modalOpen}
<Spinner />
<span>{$t('wallet.status.connecting')}</span>
{:else}
<Icon type="user-circle" class="md-show-block" />
<span>{$t('wallet.connect')}</span>
{/if}
</span>
</Button>
{/if}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as ConnectButton } from './ConnectButton.svelte';
3 changes: 2 additions & 1 deletion packages/bridge-ui-v2/src/components/Faucet/Faucet.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
import { ChainSelector } from '$components/ChainSelector';
import { TokenDropdown } from '$components/TokenDropdown';
import { testERC20Tokens } from '$libs/token';
import { srcChain } from '$stores/network';
</script>

<Card class="md:w-[524px]" title={$t('faucet.title')} text={$t('faucet.subtitle')}>
<div class="space-y-[35px]">
<div class="space-y-2">
<ChainSelector label={$t('chain_selector.currently_on')} />
<ChainSelector label={$t('chain_selector.currently_on')} value={$srcChain} />
<TokenDropdown tokens={testERC20Tokens} />
</div>

Expand Down
50 changes: 3 additions & 47 deletions packages/bridge-ui-v2/src/components/Header/Header.svelte
Original file line number Diff line number Diff line change
@@ -1,33 +1,9 @@
<script lang="ts">
import { onDestroy, onMount } from 'svelte';
import { noop } from 'svelte/internal';
import { t } from 'svelte-i18n';
import { Button } from '$components/Button';
import { ConnectButton } from '$components/ConnectButton';
import { Icon } from '$components/Icon';
import { LogoWithText } from '$components/Logo';
import { drawerToggleId } from '$components/SideNavigation';
import { Spinner } from '$components/Spinner';
import { web3modal } from '$libs/connect';
export let connected = false;
let web3modalOpen = false;
let unsubscribeWeb3Modal = noop;
function connectWallet() {
web3modal.openModal();
}
function onWeb3Modal(state: { open: boolean }) {
web3modalOpen = state.open;
}
onMount(() => {
unsubscribeWeb3Modal = web3modal.subscribeModal(onWeb3Modal);
});
onDestroy(unsubscribeWeb3Modal);
import { account } from '$stores/account';
</script>

<header
Expand All @@ -47,27 +23,7 @@
<LogoWithText class="w-[77px] h-[20px] md:hidden" />

<div class="f-items-center justify-end space-x-[10px]">
<!--
We are gonna make use of Web3Modal core button when we are connected,
which comes with interesting features out of the box.
https://docs.walletconnect.com/2.0/web/web3modal/html/wagmi/components
-->
{#if connected}
<w3m-core-button balance="show" />
{:else}
<!-- TODO: fixing the width for English. i18n? -->
<Button class="px-[20px] py-2 rounded-full w-[215px]" type="neutral" on:click={connectWallet}>
<span class="body-regular f-items-center space-x-2">
{#if web3modalOpen}
<Spinner />
<span>{$t('wallet.status.connecting')}</span>
{:else}
<Icon type="user-circle" class="md-show-block" />
<span>{$t('wallet.connect')}</span>
{/if}
</span>
</Button>
{/if}
<ConnectButton connected={$account?.isConnected} />

<label for={drawerToggleId} class="md:hidden">
<Icon type="bars-menu" />
Expand Down
9 changes: 8 additions & 1 deletion packages/bridge-ui-v2/src/components/Icon/Icon.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
| 'check-circle'
| 'info-circle'
| 'circle'
| 'arrow-right';
| 'arrow-right'
| 'up-down';
</script>

<script lang="ts">
Expand Down Expand Up @@ -129,5 +130,11 @@
fill-rule="evenodd"
clip-rule="evenodd"
d="M3 10C3 9.58579 3.33579 9.25 3.75 9.25L14.3879 9.25L10.2302 5.29062C9.93159 5.00353 9.92228 4.52875 10.2094 4.23017C10.4965 3.93159 10.9713 3.92228 11.2698 4.20937L16.7698 9.45937C16.9169 9.60078 17 9.79599 17 10C17 10.204 16.9169 10.3992 16.7698 10.5406L11.2698 15.7906C10.9713 16.0777 10.4965 16.0684 10.2094 15.7698C9.92228 15.4713 9.93159 14.9965 10.2302 14.7094L14.3879 10.75L3.75 10.75C3.33579 10.75 3 10.4142 3 10Z" />
{:else if type === 'up-down'}
<path
class={fillClass}
fill-rule="evenodd"
clip-rule="evenodd"
d="M2.23966 6.7996C2.5432 7.08145 3.01775 7.06387 3.2996 6.76034L5.25 4.6599L5.25 13.25C5.25 13.6642 5.58579 14 6 14C6.41422 14 6.75 13.6642 6.75 13.25V4.6599L8.70041 6.76034C8.98226 7.06387 9.45681 7.08145 9.76034 6.79959C10.0639 6.51774 10.0815 6.04319 9.7996 5.73966L6.5496 2.23966C6.40769 2.08684 6.20855 2 6 2C5.79145 2 5.59232 2.08684 5.45041 2.23966L2.20041 5.73966C1.91856 6.04319 1.93613 6.51774 2.23966 6.7996ZM10.2397 13.2004C9.93613 13.4823 9.91856 13.9568 10.2004 14.2603L13.4504 17.7603C13.5923 17.9132 13.7915 18 14 18C14.2086 18 14.4077 17.9132 14.5496 17.7603L17.7996 14.2603C18.0815 13.9568 18.0639 13.4823 17.7603 13.2004C17.4568 12.9186 16.9823 12.9361 16.7004 13.2397L14.75 15.3401V6.75C14.75 6.33579 14.4142 6 14 6C13.5858 6 13.25 6.33579 13.25 6.75V15.3401L11.2996 13.2397C11.0177 12.9361 10.5432 12.9186 10.2397 13.2004Z" />
{/if}
</svg>
Loading

0 comments on commit d51161d

Please sign in to comment.