Skip to content

Commit

Permalink
refactor(frontend): extract component for IC transactions scrolling
Browse files Browse the repository at this point in the history
  • Loading branch information
AntonioVentilii committed Nov 26, 2024
1 parent ff711c3 commit 346572f
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 53 deletions.
57 changes: 4 additions & 53 deletions src/frontend/src/icp/components/transactions/IcTransactions.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<script lang="ts">
import { InfiniteScroll } from '@dfinity/gix-components';
import { isNullish, nonNullish } from '@dfinity/utils';
import { nonNullish } from '@dfinity/utils';
import type { ComponentType } from 'svelte';
import { slide } from 'svelte/transition';
import { ICP_TOKEN } from '$env/tokens/tokens.icp.env';
Expand All @@ -16,28 +15,22 @@
import IcTransactionsNoListener from '$icp/components/transactions/IcTransactionsNoListener.svelte';
import IcTransactionsSkeletons from '$icp/components/transactions/IcTransactionsSkeletons.svelte';
import {
tokenAsIcToken,
tokenCkBtcLedger,
tokenCkErc20Ledger,
tokenCkEthLedger
} from '$icp/derived/ic-token.derived';
import { icTransactions } from '$icp/derived/ic-transactions.derived';
import { loadNextTransactions } from '$icp/services/ic-transactions.services';
import { icTransactionsStore } from '$icp/stores/ic-transactions.store';
import type { IcTransactionUi } from '$icp/types/ic-transaction';
import { isNotIcToken, isNotIcTokenCanistersStrict } from '$icp/validation/ic-token.validation';
import TransactionsPlaceholder from '$lib/components/transactions/TransactionsPlaceholder.svelte';
import Header from '$lib/components/ui/Header.svelte';
import { WALLET_PAGINATION } from '$lib/constants/app.constants';
import { authIdentity } from '$lib/derived/auth.derived';
import { modalIcToken, modalIcTransaction } from '$lib/derived/modal.derived';
import { nullishSignOut } from '$lib/services/auth.services';
import { i18n } from '$lib/stores/i18n.store';
import { modalStore } from '$lib/stores/modal.store';
import { token } from '$lib/stores/token.store';
import type { OptionToken } from '$lib/types/token';
import { last } from '$lib/utils/array.utils';
import { mapTransactionModalData } from '$lib/utils/transaction.utils';
import IcTransactionsScroll from '$icp/components/transactions/IcTransactionsScroll.svelte';

Check failure on line 33 in src/frontend/src/icp/components/transactions/IcTransactions.svelte

View workflow job for this annotation

GitHub Actions / lint

`$icp/components/transactions/IcTransactionsScroll.svelte` import should occur before import of `$icp/components/transactions/IcTransactionsSkeletons.svelte`
let ckEthereum: boolean;
$: ckEthereum = $tokenCkEthLedger || $tokenCkErc20Ledger;
Expand All @@ -49,48 +42,6 @@
? IcTransactionsCkEthereumListeners
: IcTransactionsNoListener;
let disableInfiniteScroll = false;
const onIntersect = async () => {
if (isNullish($authIdentity)) {
await nullishSignOut();
return;
}
const lastId = last($icTransactions)?.data.id;
if (isNullish(lastId)) {
// No transactions, we do nothing here and wait for the worker to post the first transactions
return;
}
if (typeof lastId !== 'bigint') {
// Pseudo transactions are displayed at the end of the list. There is not such use case in Oisy.
// Additionally, if it would be the case, that would mean that we display pseudo transactions at the end of the list and therefore we could assume all valid transactions have been fetched
return;
}
if (isNullish($token)) {
// Prevent unlikely events. UI wise if we are about to load the next transactions, it's probably because transactions for a loaded token have been fetched.
return;
}
if (isNotIcToken($tokenAsIcToken) || isNotIcTokenCanistersStrict($tokenAsIcToken)) {
// On one hand, we assume that the parent component does not mount this component if no transactions can be fetched; on the other hand, we want to avoid displaying an error toast that could potentially appear multiple times.
// Therefore, we do not particularly display a visual error. In any case, we cannot load transactions without an Index canister.
return;
}
await loadNextTransactions({
owner: $authIdentity.getPrincipal(),
identity: $authIdentity,
maxResults: WALLET_PAGINATION,
start: lastId,
token: $tokenAsIcToken,
signalEnd: () => (disableInfiniteScroll = true)
});
};
let selectedTransaction: IcTransactionUi | undefined;
let selectedToken: OptionToken;
$: ({ transaction: selectedTransaction, token: selectedToken } =
Expand Down Expand Up @@ -120,13 +71,13 @@
<IcTransactionsSkeletons>
<svelte:component this={additionalListener}>
{#if $icTransactions.length > 0}
<InfiniteScroll on:nnsIntersect={onIntersect} disabled={disableInfiniteScroll}>
<IcTransactionsScroll token={$token ?? ICP_TOKEN}>
{#each $icTransactions as transaction, index (`${transaction.data.id}-${index}`)}
<li in:slide={{ duration: transaction.data.status === 'pending' ? 250 : 0 }}>
<IcTransaction transaction={transaction.data} token={$token ?? ICP_TOKEN} />
</li>
{/each}
</InfiniteScroll>
</IcTransactionsScroll>
{/if}

{#if noTransactions}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<script lang="ts">
import { InfiniteScroll } from '@dfinity/gix-components';
import { isNullish } from '@dfinity/utils';
import { icTransactions } from '$icp/derived/ic-transactions.derived';
import { loadNextTransactions } from '$icp/services/ic-transactions.services';
import { isNotIcToken, isNotIcTokenCanistersStrict } from '$icp/validation/ic-token.validation';
import { WALLET_PAGINATION } from '$lib/constants/app.constants';
import { authIdentity } from '$lib/derived/auth.derived';
import { nullishSignOut } from '$lib/services/auth.services';
import { last } from '$lib/utils/array.utils';
import type { Token } from '$lib/types/token';

Check failure on line 11 in src/frontend/src/icp/components/transactions/IcTransactionsScroll.svelte

View workflow job for this annotation

GitHub Actions / lint

`$lib/types/token` type import should occur before import of `$lib/utils/array.utils`
export let token: Token;
let disableInfiniteScroll = false;
const onIntersect = async () => {
if (isNullish($authIdentity)) {
await nullishSignOut();
return;
}
const lastId = last($icTransactions)?.data.id;
if (isNullish(lastId)) {
// No transactions, we do nothing here and wait for the worker to post the first transactions
return;
}
if (typeof lastId !== 'bigint') {
// Pseudo transactions are displayed at the end of the list. There is not such use case in Oisy.
// Additionally, if it would be the case, that would mean that we display pseudo transactions at the end of the list and therefore we could assume all valid transactions have been fetched
return;
}
if (isNullish(token)) {
// Prevent unlikely events. UI wise if we are about to load the next transactions, it's probably because transactions for a loaded token have been fetched.
return;
}
if (isNotIcToken(token) || isNotIcTokenCanistersStrict(token)) {
// On one hand, we assume that the parent component does not mount this component if no transactions can be fetched; on the other hand, we want to avoid displaying an error toast that could potentially appear multiple times.
// Therefore, we do not particularly display a visual error. In any case, we cannot load transactions without an Index canister.
return;
}
await loadNextTransactions({
owner: $authIdentity.getPrincipal(),
identity: $authIdentity,
maxResults: WALLET_PAGINATION,
start: lastId,
token,
signalEnd: () => (disableInfiniteScroll = true)
});
};
</script>

<InfiniteScroll on:nnsIntersect={onIntersect} disabled={disableInfiniteScroll}>
<slot />
</InfiniteScroll>

0 comments on commit 346572f

Please sign in to comment.