Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 14 additions & 22 deletions apps/mobile/src/components/WealthChart/WealthChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ import {
useAllAccounts,
WalletAccount,
} from '@perawallet/wallet-core-accounts'
import { LoadingView } from '../LoadingView'
import { EmptyView } from '../EmptyView'
import { LoadingView } from '../LoadingView'
import {
CHART_ANIMATION_DURATION,
CHART_FOCUS_DEBOUNCE_TIME,
CHART_HEIGHT,
} from '@constants/ui'
import { getChartYAxisRange } from '@utils/chart'

export type WealthChartProps = {
account?: WalletAccount
Expand Down Expand Up @@ -74,15 +75,10 @@ export const WealthChart = ({
[data],
)

const yAxisOffsets = useMemo(() => {
const minValue = Math.min(...dataPoints.map(p => p.value))
const maxValue = Math.max(...dataPoints.map(p => p.value))
if (minValue === 0 && maxValue === 0) {
return [-1, 1]
} else {
return [minValue - minValue / 10, maxValue + maxValue / 10]
}
}, [dataPoints])
const yAxisRange = useMemo(
() => getChartYAxisRange(dataPoints),
[dataPoints],
)

const onFocus = useCallback(
({
Expand Down Expand Up @@ -113,18 +109,14 @@ export const WealthChart = ({
],
)

if (isPending) {
return (
<LoadingView
variant='circle'
size='lg'
/>
)
}

return (
<PWView style={themeStyle.container}>
{!dataPoints?.length ? (
{isPending ? (
<LoadingView
variant='circle'
size='lg'
/>
) : !dataPoints?.length ? (
<EmptyView
title=''
body={t('common.wealth_chart.empty_body')}
Expand All @@ -142,8 +134,8 @@ export const WealthChart = ({
areaChart
yAxisLabelWidth={1}
hideYAxisText
yAxisOffset={yAxisOffsets[0]}
maxValue={yAxisOffsets[1]}
yAxisOffset={yAxisRange.yAxisOffset}
maxValue={yAxisRange.maxValue}
initialSpacing={0}
endSpacing={0}
showStripOnFocus
Expand Down
2 changes: 2 additions & 0 deletions apps/mobile/src/constants/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export const SCREEN_ANIMATION_CONFIG: NativeStackNavigationOptions = {
}

export const EXPANDABLE_PANEL_ANIMATION_DURATION = 200
export const BACKUP_REMINDER_BANNER_REVEAL_DELAY = 800
export const BACKUP_REMINDER_BANNER_REVEAL_DURATION = 200
export const SLIDE_TO_CONFIRM_ANIMATION_DURATION = 250
export const LONG_NOTIFICATION_DURATION = 5000

Expand Down
3 changes: 3 additions & 0 deletions apps/mobile/src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@
"algo_gain": "You will receive {{amount}} ALGO in order to compensate the opt-in expenses."
}
},
"asset": {
"deleted_label": "(Deleted)"
},
"asset_details": {
"about": {
"title": "About {{name}}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
limitations under the License
*/

import { PWButton, PWText, PWView } from '@components/core'
import { PWButton, PWText, PWTouchableOpacity, PWView } from '@components/core'
import type { PWFlatListRef } from '@components/core'
import React, { useCallback, useEffect, useRef } from 'react'
import { useStyles } from './styles'
Expand Down Expand Up @@ -40,12 +40,14 @@ export type AccountAssetListProps = {
account: WalletAccount
scrollEnabled?: boolean
header?: React.ReactNode
isLoading?: boolean
}

export const AccountAssetList = ({
account,
scrollEnabled,
header,
isLoading = false,
}: AccountAssetListProps) => {
const listRef = useRef<PWFlatListRef>(null)
const styles = useStyles()
Expand All @@ -62,6 +64,7 @@ export const AccountAssetList = ({
optOutConfirmationState,
assetForOptOut,
isOptingOut,
headerState,
setSearchFilter,
handleConfirmOptOut,
handleCloseOptOut,
Expand Down Expand Up @@ -108,33 +111,42 @@ export const AccountAssetList = ({

const listHeader = (
<PWView style={styles.headerContainer}>
<BackupReminderBanner account={account} />
{header}
<PWView style={styles.titleBar}>
<PWText
style={styles.title}
variant='h4'
>
{t('account_details.assets.title')}
</PWText>
{!isWatch && (
<PWView style={styles.titleBarButtonContainer}>
<PWButton
icon='sliders'
variant='helper'
paddingStyle='dense'
onPress={manageSheetState.open}
/>
<PWButton
icon='plus'
title={t('account_details.assets.add_asset')}
variant='helper'
paddingStyle='dense'
onPress={addAssetSheetState.open}
/>
<BackupReminderBanner
account={account}
isLoading={isLoading}
/>
{headerState.isOpen && (
<>
{header}
<PWView style={styles.titleBar}>
<PWText
style={styles.title}
variant='h4'
>
{t('account_details.assets.title')}
</PWText>
{!isWatch && (
<PWView style={styles.titleBarButtonContainer}>
<PWButton
icon='sliders'
variant='helper'
paddingStyle='dense'
onPress={manageSheetState.open}
/>
<PWButton
icon='plus'
title={t(
'account_details.assets.add_asset',
)}
variant='helper'
paddingStyle='dense'
onPress={addAssetSheetState.open}
/>
</PWView>
)}
</PWView>
)}
</PWView>
</>
)}
</PWView>
)

Expand All @@ -145,38 +157,43 @@ export const AccountAssetList = ({
behavior='padding'
style={styles.keyboardAvoidingViewContainer}
>
<SearchableList
ref={listRef}
data={balances}
renderItem={renderItem}
scrollEnabled={scrollEnabled}
keyExtractor={item => item.assetId}
estimatedItemSize={72}
recycleItems
automaticallyAdjustKeyboardInsets
keyboardDismissMode='interactive'
contentContainerStyle={styles.rootContainer}
ListHeaderComponent={listHeader}
searchPlaceholder={t(
'account_details.assets.search_placeholder',
)}
onSearchChange={setSearchFilter}
ListEmptyComponent={
isPending ? (
<LoadingView
variant='skeleton'
size='sm'
count={8}
style={styles.loading}
/>
) : (
<EmptyView
title={getEmptyTitle()}
body={getEmptyBody()}
/>
)
}
/>
<PWTouchableOpacity
style={styles.keyboardAvoidingViewContainer}
onPress={headerState.open}
>
<SearchableList
ref={listRef}
data={balances}
renderItem={renderItem}
scrollEnabled={scrollEnabled}
keyExtractor={item => item.assetId}
estimatedItemSize={72}
recycleItems
automaticallyAdjustKeyboardInsets
keyboardDismissMode='interactive'
contentContainerStyle={styles.rootContainer}
ListHeaderComponent={listHeader}
searchPlaceholder={t(
'account_details.assets.search_placeholder',
)}
onSearchChange={setSearchFilter}
ListEmptyComponent={
isPending ? (
<LoadingView
variant='skeleton'
size='sm'
count={8}
style={styles.loading}
/>
) : (
<EmptyView
title={getEmptyTitle()}
body={getEmptyBody()}
/>
)
}
/>
</PWTouchableOpacity>

<ManageAssetsBottomSheet
isVisible={manageSheetState.isOpen}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
*/

import { render, screen } from '@test-utils/render'
import { describe, it, expect, vi, beforeEach } from 'vitest'
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
import { act } from 'react'
import { BACKUP_REMINDER_BANNER_REVEAL_DELAY } from '@constants/ui'
import { AccountAssetList } from '../AccountAssetList'
import {
WalletAccount,
Expand Down Expand Up @@ -253,15 +255,27 @@ describe('AccountAssetList', () => {
describe('backup banner integration', () => {
beforeEach(() => {
mockBackupReminderBannerHook.mockReset()
vi.useFakeTimers()
})

afterEach(() => {
vi.useRealTimers()
})

const advancePastRevealDelay = () => {
act(() => {
vi.advanceTimersByTime(BACKUP_REMINDER_BANNER_REVEAL_DELAY)
})
}

it('renders backup reminder banner when hook reports visible', () => {
mockBackupReminderBannerHook.mockReturnValue({
isVisible: true,
onPress: vi.fn(),
})

render(<AccountAssetList account={mockAccount} />)
advancePastRevealDelay()

expect(screen.getByTestId('backup_reminder_banner')).toBeTruthy()
})
Expand All @@ -275,6 +289,7 @@ describe('AccountAssetList', () => {
const { queryByTestId } = render(
<AccountAssetList account={mockAccount} />,
)
advancePastRevealDelay()

expect(queryByTestId('backup_reminder_banner')).toBeNull()
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type UseAccountAssetListResult = {
hideZeroBalance: boolean
assetSortMode: AssetSortMode
searchFilter: string
headerState: ModalState
manageSheetState: ModalState
sortSheetState: ModalState
filterSheetState: ModalState
Expand Down Expand Up @@ -79,6 +80,7 @@ export const useAccountAssetList = ({
account,
t,
}: UseAccountAssetListParams): UseAccountAssetListResult => {
const headerState = useModalState(true)
const manageSheetState = useModalState(false)
const sortSheetState = useModalState(false)
const filterSheetState = useModalState(false)
Expand Down Expand Up @@ -161,6 +163,7 @@ export const useAccountAssetList = ({

const goToAssetScreen = useCallback(
(item: AssetWithAccountBalance) => {
headerState.open()
const assetInfo = assets?.get(item.assetId)
if (assetInfo && isCollectible(assetInfo)) {
navigation.navigate('CollectibleDetails', {
Expand All @@ -172,7 +175,7 @@ export const useAccountAssetList = ({
})
}
},
[navigation, assets],
[headerState, navigation, assets],
)

const handleOptOut = useCallback(
Expand Down Expand Up @@ -279,6 +282,7 @@ export const useAccountAssetList = ({
hideZeroBalance,
assetSortMode,
searchFilter,
headerState,
manageSheetState,
sortSheetState,
filterSheetState,
Expand Down
Loading
Loading