Skip to content

Commit

Permalink
feat(bridge-ui-v2): Activities page (#14504)
Browse files Browse the repository at this point in the history
Co-authored-by: Francisco <jscriptcoder@gmail.com>
  • Loading branch information
KorbinianK and jscriptcoder committed Aug 15, 2023
1 parent 7bca3d0 commit 4dff4b3
Show file tree
Hide file tree
Showing 69 changed files with 5,873 additions and 784 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,7 @@ __pycache__/
# Ignore .husky for new contributors using lefthook while maintaining
# backwards compatibility for past contributors
.husky


# VSCode
.vscode/launch.json
1 change: 0 additions & 1 deletion packages/branding/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,3 @@ Look inside of this package for some common files you can use. Otherwise, please
## Colors

Our primary hex color is `#E81899`. For the full color palette and further details, please resort to the [Figma](<https://www.figma.com/file/qVALIk5srW9nvOJwl6NF6F/Taiko-Brand-Guidelines-(External)>).

14 changes: 14 additions & 0 deletions packages/bridge-ui-v2/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ export PUBLIC_L1_TOKEN_VAULT_ADDRESS=0x
export PUBLIC_L2_TOKEN_VAULT_ADDRESS=0x
export PUBLIC_L3_TOKEN_VAULT_ADDRESS=0x

# ERC721 Token Vault Contract address
export PUBLIC_L1_ERC721_VAULT_ADDRESS=
export PUBLIC_L2_ERC721_VAULT_ADDRESS=
export PUBLIC_L3_ERC721_VAULT_ADDRESS=


# ERC1155 Token Vault Contract address
export PUBLIC_L1_ERC1155_VAULT_ADDRESS=
export PUBLIC_L2_ERC1155_VAULT_ADDRESS=
export PUBLIC_L3_ERC1155_VAULT_ADDRESS=


# Bridge Contract address
export PUBLIC_L1_BRIDGE_ADDRESS=0x
Expand All @@ -61,6 +72,9 @@ export PUBLIC_TEST_ERC20=[]
# WalletConnect Project ID
export PUBLIC_WALLETCONNECT_PROJECT_ID=""

# Enable NFT Bridge ("true" or "false")
export PUBLIC_NFT_BRIDGE_ENABLED=""


# Sentry
export PUBLIC_SENTRY_DSN=https://
Expand Down
8 changes: 6 additions & 2 deletions packages/bridge-ui-v2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"@typescript-eslint/parser": "^5.45.0",
"@vitest/coverage-v8": "^0.33.0",
"@wagmi/cli": "^1.0.1",
"abitype": "^0.8.7",
"autoprefixer": "^10.4.14",
"daisyui": "3.1.7",
"eslint": "^8.28.0",
Expand All @@ -37,6 +38,7 @@
"eslint-plugin-svelte": "^2.26.0",
"ethereum-address": "^0.0.4",
"jsdom": "^22.1.0",
"lokijs": "^1.5.12",
"postcss": "^8.4.24",
"prettier": "^3.0.0",
"prettier-plugin-svelte": "^3.0.0",
Expand All @@ -56,9 +58,11 @@
"@web3modal/ethereum": "^2.6.2",
"@web3modal/html": "^2.6.2",
"@zerodevx/svelte-toast": "^0.9.5",
"abitype": "^0.8.2",
"axios": "^1.4.0",
"buffer": "^6.0.3",
"debug": "^4.3.4",
"events": "^3.3.0",
"svelte-i18n": "^3.6.0",
"viem": "^1.2.9"
"viem": "^1.4.1"
}
}
19 changes: 19 additions & 0 deletions packages/bridge-ui-v2/src/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,22 @@ export const bridgeService = {
export const pendingTransaction = {
waitTimeout: 300_000,
};

export const storageService = {
bridgeTxPrefix: 'transactions',
customTokenPrefix: 'custom-tokens',
};

export const bridgeTransactionPoller = {
interval: 20_000,
};

export const statusComponent = {
minimumEthToClaim: 0.0001,
};

export const activitiesConfig = {
pageSizeDesktop: 6,
pageSizeMobile: 4,
blurTransitionTime: 300,
};
190 changes: 175 additions & 15 deletions packages/bridge-ui-v2/src/components/Activities/Activities.svelte
Original file line number Diff line number Diff line change
@@ -1,25 +1,185 @@
<script lang="ts">
import { onMount } from 'svelte';
import { t } from 'svelte-i18n';
import type { Address } from 'viem';
import { Card } from '$components/Card';
import { ChainSelector } from '$components/ChainSelector';
import { network } from '$stores/network';
import ChainSelector from '$components/ChainSelector/ChainSelector.svelte';
import { DesktopOrLarger } from '$components/DesktopOrLarger';
import OnAccount from '$components/OnAccount/OnAccount.svelte';
import { Paginator } from '$components/Paginator';
import { Spinner } from '$components/Spinner';
import { activitiesConfig } from '$config';
import { type BridgeTransaction, fetchTransactions } from '$libs/bridge';
import { web3modal } from '$libs/connect';
import { bridgeTxService } from '$libs/storage';
import { account, network } from '$stores';
import type { Account } from '$stores/account';
import ListWithDetailsView from './ListWithDetailsView.svelte';
import TableView from './TableView.svelte';
import MobileDetailsDialog from './MobileDetailsDialog.svelte';
import StatusInfoDialog from './StatusInfoDialog.svelte';
import Transaction from './Transaction.svelte';
let transactions: BridgeTransaction[] = [];
let currentPage = 1;
let isBlurred = false;
const transitionTime = activitiesConfig.blurTransitionTime;
let totalItems = 0;
let pageSize = activitiesConfig.pageSizeDesktop;
let loadingTxs = false;
let detailsOpen = false;
let isDesktopOrLarger: boolean;
let selectedItem: BridgeTransaction | null = null;
const handlePageChange = (detail: number) => {
isBlurred = true;
setTimeout(() => {
currentPage = detail;
isBlurred = false;
}, transitionTime);
};
const getTransactionsToShow = (page: number, pageSize: number, bridgeTx: BridgeTransaction[]) => {
const start = (page - 1) * pageSize;
const end = start + pageSize;
return bridgeTx.slice(start, end);
};
const onWalletConnect = () => web3modal.openModal();

Check warning on line 54 in packages/bridge-ui-v2/src/components/Activities/Activities.svelte

View workflow job for this annotation

GitHub Actions / build

'onWalletConnect' is assigned a value but never used
const onAccountChange = async (newAccount: Account, oldAccount?: Account) => {
// We want to make sure that we are connected and only
// fetch if the account has changed
if (newAccount?.isConnected && newAccount.address && newAccount.address !== oldAccount?.address) {
loadingTxs = true;
try {
updateTransactions(newAccount.address);
} catch (err) {
console.error(err);
// TODO: handle
} finally {
loadingTxs = false;
}
}
};
const closeDetails = () => {
detailsOpen = false;
selectedItem = null;
};
const openDetails = (tx: BridgeTransaction) => {
detailsOpen = true;
selectedItem = tx;
};
const updateTransactions = async (address: Address) => {
const { mergedTransactions, outdatedLocalTransactions } = await fetchTransactions(address);
transactions = mergedTransactions;
if (outdatedLocalTransactions.length > 0) {
await bridgeTxService.removeTransactions(address, outdatedLocalTransactions);
}
};
onMount(async () => {
// We want to make sure that we are connected before fetching
if (!$account?.isConnected || !$account?.address) return;
loadingTxs = true;
try {
await updateTransactions($account.address);
} catch (err) {
console.error(err);
// TODO: handle
} finally {
loadingTxs = false;
}
});
$: pageSize = isDesktopOrLarger ? activitiesConfig.pageSizeDesktop : activitiesConfig.pageSizeMobile;
$: transactionsToShow = getTransactionsToShow(currentPage, pageSize, transactions);
$: totalItems = transactions.length;
// Some shortcuts to make the code more readable
$: isConnected = $account?.isConnected;
$: hasTxs = transactions.length > 0;
// Controls what we render on the page
$: renderLoading = loadingTxs && isConnected;
$: renderTransactions = !renderLoading && isConnected && hasTxs;
$: renderNoTransactions = !renderLoading && !renderTransactions;
</script>

<Card class="md:min-w-[524px]" title={$t('activities.title')} text={$t('activities.description')}>
<div class="space-y-[35px]">
<ChainSelector label={$t('chain_selector.currently_on')} value={$network} small />
<!-- Small size view -->
<div class="md:hidden">
<ListWithDetailsView />
</div>
<div class="flex flex-col justify-center w-full">
<Card title={$t('activities.title')} text={$t('activities.description')}>
<ChainSelector class="py-[35px] " label={$t('chain_selector.currently_on')} value={$network} switchWallet small />
<div class="flex flex-col" style={`min-height: calc(${transactionsToShow.length} * 80px);`}>
{#if isDesktopOrLarger}
<div class="h-sep" />
<div class="text-white flex">
<div class="w-1/5 py-2">{$t('activities.header.from')}</div>
<div class="w-1/5 py-2">{$t('activities.header.to')}</div>
<div class="w-1/5 py-2">{$t('activities.header.amount')}</div>
<div class="w-1/5 py-2 flex flex-row">
{$t('activities.header.status')}
<StatusInfoDialog />
</div>
<div class="w-1/5 py-2">{$t('activities.header.explorer')}</div>
</div>
<div class="h-sep" />
{/if}

<!-- Medium size view: desktop and larger -->
<div class="hidden md:block">
<TableView />
{#if renderLoading}
<div class="flex items-center justify-center text-white h-[80px]">
<Spinner /> <span class="pl-3">{$t('common.loading')}...</span>
</div>
{/if}

{#if renderTransactions}
<div
class="flex flex-col items-center"
style={isBlurred ? `filter: blur(5px); transition: filter ${transitionTime / 1000}s ease-in-out` : ''}>
{#each transactionsToShow as item (item.hash)}
<Transaction {item} on:click={isDesktopOrLarger ? undefined : () => openDetails(item)} />
<div class="h-sep" />
{/each}
</div>
{/if}

{#if renderNoTransactions}
<div class="flex items-center justify-center text-white h-[80px]">
<span class="pl-3">{$t('activities.no_transactions')}</span>
</div>
{/if}

<!-- TODO: we don't have this in the design -->
<!-- {#if !$account?.isConnected}
<div class="flex items-center justify-center text-white h-[80px]">
<Button type="primary" on:click={onWalletConnect} class="px-[28px] py-[14px] ">
<span class="body-bold">{$t('wallet.connect')}</span>
</Button>
</div>
{/if} -->
</div>
</Card>

<div class="flex justify-end pt-2">
<Paginator {pageSize} {totalItems} on:pageChange={({ detail }) => handlePageChange(detail)} />
</div>
</Card>
</div>

<MobileDetailsDialog {closeDetails} {detailsOpen} {selectedItem} />

<OnAccount change={onAccountChange} />

<DesktopOrLarger bind:is={isDesktopOrLarger} />
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<script lang="ts">
import { chainIcons, type ChainID, getChainName } from '$libs/chain';
export let chainId: ChainID;
const chainName = getChainName(Number(chainId));
const icon = chainIcons[Number(chainId)];
</script>

<div class="flex md:items-stretch self-center justify-items-start'}">
<img src={icon} alt="chain-logo" class="rounded-full w-5 h-5 hidden md:block mr-2" />
<span class="md:font-bold font-normal">{chainName}</span>
</div>
Loading

0 comments on commit 4dff4b3

Please sign in to comment.