Skip to content

Commit

Permalink
feat(bridge-ui-v2): Faucet (#14145)
Browse files Browse the repository at this point in the history
Co-authored-by: Korbinian <KorbinianK@users.noreply.github.com>
  • Loading branch information
jscriptcoder and KorbinianK committed Jul 12, 2023
1 parent 077b2a1 commit b2f2388
Show file tree
Hide file tree
Showing 34 changed files with 595 additions and 153 deletions.
2 changes: 1 addition & 1 deletion packages/bridge-ui-v2/src/components/Alert/Alert.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
};
const classes = classNames(
'alert gap-[5px] py-[12px] px-[20px] rounded-[10px]',
'alert flex gap-[5px] py-[12px] px-[20px] rounded-[10px]',
type ? typeMap[type].class : null,
forceColumnFlow ? 'grid-flow-col text-left' : null,
$$props.class,
Expand Down
24 changes: 2 additions & 22 deletions packages/bridge-ui-v2/src/components/Bridge/Bridge.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<script lang="ts">
import type { Chain } from '@wagmi/core';
import { t } from 'svelte-i18n';
import AmountInput from '$components/AmountInput';
Expand All @@ -10,34 +9,15 @@
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')} value={$srcChain} onChange={onSrcChainChange} />
<ChainSelector label={$t('chain.from')} value={$srcChain} />
<TokenDropdown {tokens} />
</div>

Expand All @@ -50,7 +30,7 @@
</div>

<div class="space-y-2">
<ChainSelector label={$t('chain.to')} value={$destChain} onChange={onDestChainChange} />
<ChainSelector label={$t('chain.to')} value={$destChain} />
<RecipientInput />
</div>
</div>
Expand Down
22 changes: 21 additions & 1 deletion packages/bridge-ui-v2/src/components/Button/Button.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script lang="ts">
import { Spinner } from '$components/Spinner';
import { classNames } from '$libs/util/classNames';
type ButtonType =
Expand All @@ -16,6 +17,7 @@
export let type: Maybe<ButtonType> = null;
export let shape: Maybe<ButtonShape> = null;
export let loading = false;
export let outline = false;
export let block = false;
export let wide = false;
Expand All @@ -42,17 +44,35 @@
square: 'btn-square',
};
const classes = classNames(
$: classes = classNames(
'btn w-full h-auto min-h-fit border-0',
type === 'primary' ? 'body-bold' : 'body-regular',
type ? typeMap[type] : null,
shape ? shapeMap[shape] : null,
outline ? 'btn-outline' : null,
block ? 'btn-block' : null,
wide ? 'btn-wide' : null,
// For loading state we want to see well the content,
// since we're showing some important information.
loading ? 'btn-disabled !text-primary-content' : null,
$$props.class,
);
// Make sure to disable the button if we're in loading state
$: if (loading) {
$$restProps.disabled = true;
}
</script>

<button {...$$restProps} class={classes} on:click>
{#if loading}
<Spinner />
{/if}

<slot />
</button>
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
<script lang="ts">
import type { Chain, GetNetworkResult } from '@wagmi/core';
import { type Chain, type GetNetworkResult, switchNetwork } from '@wagmi/core';
import type { ComponentType } from 'svelte';
import { noop, onDestroy } from 'svelte/internal';
import { onDestroy } from 'svelte/internal';
import { t } from 'svelte-i18n';
import { UserRejectedRequestError } from 'viem';
import { EthIcon, Icon, TaikoIcon } from '$components/Icon';
import { LoadingMask } from '$components/LoadingMask';
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> = {
[PUBLIC_L1_CHAIN_ID]: EthIcon,
[PUBLIC_L2_CHAIN_ID]: TaikoIcon,
};
let switchingNetwork = false;
let buttonId = `button-${uid()}`;
let dialogId = `dialog-${uid()}`;
let modalOpen = false;
Expand All @@ -41,12 +41,23 @@
modalOpen = true;
}
function selectChain(chain: Chain) {
if (chain === value) return;
async function selectChain(chain: Chain) {
if (chain.id === value?.id) return;
switchingNetwork = true;
value = chain;
onChange?.(chain); // TODO: data binding? 🤔
closeModal();
try {
await switchNetwork({ chainId: chain.id });
closeModal();
} catch (error) {
console.error(error);
if (error instanceof UserRejectedRequestError) {
warningToast($t('messages.network.rejected'));
}
} finally {
switchingNetwork = false;
}
}
function getChainKeydownHandler(chain: Chain) {
Expand Down Expand Up @@ -86,22 +97,33 @@
</div>

<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" />
<div class="modal-box relative px-6 py-[35px] md:py-[20px] bg-primary-base-background text-primary-base-content">
{#if switchingNetwork}
<LoadingMask
class="bg-grey-0/60"
spinnerClass="border-primary-base-content"
text={$t('messages.network.switching')} />
{/if}

<button class="absolute right-6 top-[35px] md:top-[20px]" on:click={closeModal}>
<Icon type="x-close" fillClass="fill-secondary-icon" size={24} />
</button>
<h3 class="title-body-bold">{$t('chain_selector.placeholder')}</h3>
<ul class="menu space-y-4">
<h3 class="title-body-bold mb-[20px]">{$t('chain_selector.placeholder')}</h3>
<ul role="menu" class="space-y-4">
{#each chains as chain (chain.id)}
{@const disabled = chain.id === value?.id}
<li
role="menuitem"
tabindex="0"
class:opacity-50={chain === value}
aria-disabled={chain === value}
class="p-4 rounded-[10px]"
class:opacity-20={disabled}
class:hover:bg-grey-10={!disabled}
class:hover:cursor-pointer={!disabled}
aria-disabled={disabled}
on:click={() => selectChain(chain)}
on:keydown={getChainKeydownHandler(chain)}>
<!-- TODO: agree on hover:bg color -->
<div class="f-row justify-between hover:text-primary-base-content hover:bg-grey-10">
<div class="f-row justify-between">
<div class="f-items-center space-x-4">
<i role="img" aria-label={chain.name}>
<svelte:component this={chainToIconMap[chain.id]} size={32} />
Expand All @@ -114,7 +136,5 @@
{/each}
</ul>
</div>

<div class="overlay-backdrop" />
</dialog>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,23 @@
import { t } from 'svelte-i18n';
import { Button } from '$components/Button';
import { DesktopOrLarger } from '$components/DesktopOrLarger';
import { Icon } from '$components/Icon';
import { Spinner } from '$components/Spinner';
import { web3modal } from '$libs/connect';
export let connected = false;
// Will help us to programmatically show or hide the balance of
// the web3modal core button
let isDesktopOrLarger: boolean;
let web3modalOpen = false;
let unsubscribeWeb3Modal = noop;
$: web3ButtonBalance = connected && isDesktopOrLarger ? 'show' : 'hide';
function connectWallet() {
if (web3modalOpen) return;
web3modal.openModal();
}
Expand All @@ -28,19 +35,20 @@
onDestroy(unsubscribeWeb3Modal);
</script>

<DesktopOrLarger bind:is={isDesktopOrLarger} />

<!--
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" />
<w3m-core-button balance={web3ButtonBalance} />
{:else}
<!-- TODO: fixing the width for English. i18n? -->
<Button class="px-[20px] py-2 rounded-full w-[215px]" type="neutral" on:click={connectWallet}>
<Button class="px-[20px] py-2 rounded-full w-[215px]" type="neutral" loading={web3modalOpen} 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" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<script lang="ts">
import { onDestroy, onMount } from 'svelte';
// This component will help us to programmatically do the same as
// CSS media queries. We can use it to show/hide elements or render
// different components based on whether or not the size is desktop
// or larger
const mediaQuery = window.matchMedia('(min-width: 768px)');
export let is: boolean;
function mediaQueryHandler(event: MediaQueryListEvent) {
is = event.matches;
}
onMount(() => {
is = mediaQuery.matches;
mediaQuery.addEventListener('change', mediaQueryHandler);
});
onDestroy(() => {
mediaQuery.removeEventListener('change', mediaQueryHandler);
});
// TODO: maybe we want something more general purpose than just `md`?
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as DesktopOrLarger } from './DesktopOrLarger.svelte';

0 comments on commit b2f2388

Please sign in to comment.