Skip to content

Commit bcbe467

Browse files
committed
complete rework of the token and collectible views
1 parent 9735a51 commit bcbe467

File tree

14 files changed

+431
-395
lines changed

14 files changed

+431
-395
lines changed

packages/react-wallet/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
},
3333
"dependencies": {
3434
"@radix-ui/react-popover": "^1.0.7",
35+
"micro-observables": "1.7.2",
3536
"dayjs": "^1.11.11",
3637
"fuse.js": "^6.6.2",
3738
"qrcode.react": "^4.0.1",

packages/react-wallet/src/components/InfiniteScroll.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,21 @@ export const useIntersectionObserver = (ref: RefObject<Element | null>, options?
2222
interface InfiniteScrollProps {
2323
onLoad: (pageNumber: number) => Promise<any>
2424
hasMore?: boolean
25+
resetTrigger?: boolean
2526
}
2627

2728
export const InfiniteScroll = (props: PropsWithChildren<InfiniteScrollProps>) => {
28-
const { onLoad, hasMore = true, children } = props
29+
const { onLoad, hasMore = true, children, resetTrigger } = props
2930

3031
const [pageNumber, setPageNumber] = useState(0)
3132
const [isLoading, setLoading] = useState(false)
3233
const bottomRef = useRef<HTMLDivElement>(null)
3334
const isBottom = useIntersectionObserver(bottomRef)
3435

36+
useEffect(() => {
37+
setPageNumber(0)
38+
}, [resetTrigger])
39+
3540
useEffect(() => {
3641
if (isBottom && hasMore && !isLoading) {
3742
handleLoad()

packages/react-wallet/src/components/SlideupDrawer.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,14 @@ export const SlideupDrawer = ({
4949
position: 'absolute',
5050
bottom: 0,
5151
left: 0,
52-
width: '100%'
52+
width: '100%',
53+
height: '80%',
54+
display: 'flex',
55+
flexDirection: 'column'
5356
}}
5457
onClick={e => e.stopPropagation()}
5558
>
56-
<Card className="p-0 bg-background-primary">
59+
<Card className="bg-background-primary p-0" style={{ flex: 1 }}>
5760
<Card className={cn('flex flex-row rounded-none pt-2', onBackPress ? 'justify-between' : 'justify-center')}>
5861
{onBackPress && (
5962
<Button variant="text" className="pt-2" onClick={onBackPress}>
@@ -72,7 +75,9 @@ export const SlideupDrawer = ({
7275
</div>
7376
{onBackPress && <div style={{ width: '20px' }}></div>}
7477
</Card>
75-
<Card className="rounded-none bg-background-raised">{children}</Card>
78+
<Card className="rounded-none bg-background-raised" style={{ height: '80%', overflowY: 'auto' }}>
79+
{children}
80+
</Card>
7681
<Divider className="my-0" />
7782
<Card className="rounded-none">
7883
<div

packages/react-wallet/src/hooks/useSettings.ts

Lines changed: 96 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
11
import { ConnectedWallet, useWallets, LocalStorageKey, useWalletSettings } from '@0xsequence/react-connect'
2-
import { useState } from 'react'
2+
import { Observable, observable } from 'micro-observables'
33
import { useConfig } from 'wagmi'
44

55
import { FiatCurrency, defaultFiatCurrency } from '../constants'
66

7+
interface MutableObservable<T> extends Observable<T> {
8+
set(value: T): void
9+
}
10+
711
interface Settings {
812
hideCollectibles: boolean
913
hideUnlistedTokens: boolean
1014
fiatCurrency: FiatCurrency
1115
selectedNetworks: number[]
16+
allNetworks: number[]
1217
selectedWallets: ConnectedWallet[]
1318
selectedCollections: string[]
19+
hideCollectiblesObservable: Observable<boolean>
20+
hideUnlistedTokensObservable: Observable<boolean>
21+
fiatCurrencyObservable: Observable<FiatCurrency>
22+
selectedNetworksObservable: Observable<number[]>
23+
selectedWalletsObservable: Observable<ConnectedWallet[]>
24+
selectedCollectionsObservable: Observable<string[]>
1425
setFiatCurrency: (newFiatCurrency: FiatCurrency) => void
1526
setHideCollectibles: (newState: boolean) => void
1627
setHideUnlistedTokens: (newState: boolean) => void
@@ -19,27 +30,33 @@ interface Settings {
1930
setSelectedCollections: (newCollections: string[]) => void
2031
}
2132

22-
type SettingsItems = Pick<
23-
Settings,
24-
'hideCollectibles' | 'hideUnlistedTokens' | 'fiatCurrency' | 'selectedWallets' | 'selectedNetworks' | 'selectedCollections'
25-
>
33+
type SettingsItems = {
34+
hideCollectiblesObservable: MutableObservable<boolean>
35+
hideUnlistedTokensObservable: MutableObservable<boolean>
36+
fiatCurrencyObservable: MutableObservable<FiatCurrency>
37+
selectedWalletsObservable: MutableObservable<ConnectedWallet[]>
38+
selectedNetworksObservable: MutableObservable<number[]>
39+
selectedCollectionsObservable: MutableObservable<string[]>
40+
}
41+
42+
let settingsObservables: SettingsItems | null = null
2643

2744
export const useSettings = (): Settings => {
2845
const { readOnlyNetworks, displayedAssets } = useWalletSettings()
2946
const { chains } = useConfig()
3047
const { wallets: allWallets } = useWallets()
3148

32-
const allChains = [
49+
const allNetworks = [
3350
...new Set([...chains.map(chain => chain.id), ...(readOnlyNetworks || []), ...displayedAssets.map(asset => asset.chainId)])
3451
]
3552

3653
const getSettingsFromStorage = (): SettingsItems => {
3754
let hideUnlistedTokens = true
3855
let hideCollectibles = false
3956
let fiatCurrency = defaultFiatCurrency
40-
const selectedWallets: ConnectedWallet[] = allWallets
41-
let selectedNetworks: number[] = allChains
42-
const selectedCollections: string[] = []
57+
let selectedWallets: ConnectedWallet[] = allWallets
58+
let selectedNetworks: number[] = allNetworks
59+
let selectedCollections: string[] = []
4360

4461
try {
4562
const settingsStorage = localStorage.getItem(LocalStorageKey.Settings)
@@ -54,98 +71,118 @@ export const useSettings = (): Settings => {
5471
if (settings?.fiatCurrency !== undefined) {
5572
fiatCurrency = settings?.fiatCurrency as FiatCurrency
5673
}
74+
if (settings?.selectedWallets !== undefined) {
75+
selectedWallets = settings?.selectedWallets as ConnectedWallet[]
5776

77+
const hasInvalidWallets = selectedWallets.some(
78+
wallet => !allWallets.some((w: ConnectedWallet) => w.address === wallet.address)
79+
)
80+
81+
const isPartialSelection = selectedWallets.length > 1 && selectedWallets.length !== allWallets.length
82+
83+
if (hasInvalidWallets || isPartialSelection) {
84+
selectedWallets = allWallets
85+
}
86+
}
5887
if (settings?.selectedNetworks !== undefined) {
5988
let areSelectedNetworksValid = true
6089
settings.selectedNetworks.forEach((chainId: number) => {
61-
if (allChains.find(chain => chain === chainId) === undefined) {
90+
if (allNetworks.find(chain => chain === chainId) === undefined) {
6291
areSelectedNetworksValid = false
6392
}
6493
})
6594
if (areSelectedNetworksValid) {
6695
selectedNetworks = settings?.selectedNetworks as number[]
6796
}
6897
}
98+
if (settings?.selectedCollections !== undefined) {
99+
selectedCollections = settings?.selectedCollections as string[]
100+
}
69101
} catch (e) {
70102
console.error(e, 'Failed to fetch settings')
71103
}
72104

105+
console.log('Creating observable instance', Math.random())
106+
73107
return {
74-
hideUnlistedTokens,
75-
hideCollectibles,
76-
fiatCurrency,
77-
selectedWallets,
78-
selectedNetworks,
79-
selectedCollections
108+
hideUnlistedTokensObservable: observable(hideUnlistedTokens),
109+
hideCollectiblesObservable: observable(hideCollectibles),
110+
fiatCurrencyObservable: observable(fiatCurrency),
111+
selectedWalletsObservable: observable(selectedWallets),
112+
selectedNetworksObservable: observable(selectedNetworks),
113+
selectedCollectionsObservable: observable(selectedCollections)
80114
}
81115
}
82-
const defaultSettings = getSettingsFromStorage()
83116

84-
const [settings, setSettings] = useState(defaultSettings)
117+
if (!settingsObservables) {
118+
settingsObservables = getSettingsFromStorage()
119+
}
120+
121+
const {
122+
hideUnlistedTokensObservable,
123+
hideCollectiblesObservable,
124+
fiatCurrencyObservable,
125+
selectedWalletsObservable,
126+
selectedNetworksObservable,
127+
selectedCollectionsObservable
128+
} = settingsObservables
85129

86130
const setHideUnlistedTokens = (newState: boolean) => {
87-
const oldSettings = getSettingsFromStorage()
88-
const newSettings = {
89-
...oldSettings,
90-
hideUnlistedTokens: newState
91-
}
92-
localStorage.setItem(LocalStorageKey.Settings, JSON.stringify(newSettings))
93-
setSettings(newSettings)
131+
hideUnlistedTokensObservable.set(newState)
132+
updateLocalStorage()
94133
}
95134

96-
// TODO: remove later
97135
const setHideCollectibles = (newState: boolean) => {
98-
const oldSettings = getSettingsFromStorage()
99-
const newSettings = {
100-
...oldSettings,
101-
hideCollectibles: newState
102-
}
103-
localStorage.setItem(LocalStorageKey.Settings, JSON.stringify(newSettings))
104-
setSettings(newSettings)
136+
hideCollectiblesObservable.set(newState)
137+
updateLocalStorage()
105138
}
106139

107140
const setFiatCurrency = (newFiatCurrency: FiatCurrency) => {
108-
const oldSettings = getSettingsFromStorage()
109-
const newSettings = {
110-
...oldSettings,
111-
fiatCurrency: newFiatCurrency
112-
}
113-
localStorage.setItem(LocalStorageKey.Settings, JSON.stringify(newSettings))
114-
setSettings(newSettings)
141+
fiatCurrencyObservable.set(newFiatCurrency)
142+
updateLocalStorage()
115143
}
116144

117145
const setSelectedWallets = (newSelectedWallets: ConnectedWallet[]) => {
118-
const oldSettings = getSettingsFromStorage()
119-
const newSettings = {
120-
...oldSettings,
121-
selectedWallets: newSelectedWallets
122-
}
123-
localStorage.setItem(LocalStorageKey.Settings, JSON.stringify(newSettings))
124-
setSettings(newSettings)
146+
selectedWalletsObservable.set(newSelectedWallets)
147+
updateLocalStorage()
125148
}
126149

127150
const setSelectedNetworks = (newSelectedNetworks: number[]) => {
128-
const oldSettings = getSettingsFromStorage()
129-
const newSettings = {
130-
...oldSettings,
131-
selectedNetworks: newSelectedNetworks
132-
}
133-
localStorage.setItem(LocalStorageKey.Settings, JSON.stringify(newSettings))
134-
setSettings(newSettings)
151+
selectedNetworksObservable.set(newSelectedNetworks)
152+
updateLocalStorage()
135153
}
136154

137155
const setSelectedCollections = (newSelectedCollections: string[]) => {
138-
const oldSettings = getSettingsFromStorage()
156+
selectedCollectionsObservable.set(newSelectedCollections)
157+
updateLocalStorage()
158+
}
159+
160+
const updateLocalStorage = () => {
139161
const newSettings = {
140-
...oldSettings,
141-
selectedCollections: newSelectedCollections
162+
hideUnlistedTokens: hideUnlistedTokensObservable.get(),
163+
hideCollectibles: hideCollectiblesObservable.get(),
164+
fiatCurrency: fiatCurrencyObservable.get(),
165+
selectedWallets: selectedWalletsObservable.get(),
166+
selectedNetworks: selectedNetworksObservable.get(),
167+
selectedCollections: selectedCollectionsObservable.get()
142168
}
143169
localStorage.setItem(LocalStorageKey.Settings, JSON.stringify(newSettings))
144-
setSettings(newSettings)
145170
}
146171

147172
return {
148-
...settings,
173+
hideUnlistedTokens: hideUnlistedTokensObservable.get(),
174+
hideCollectibles: hideCollectiblesObservable.get(),
175+
fiatCurrency: fiatCurrencyObservable.get(),
176+
selectedWallets: selectedWalletsObservable.get(),
177+
selectedNetworks: selectedNetworksObservable.get(),
178+
allNetworks: allNetworks,
179+
selectedCollections: selectedCollectionsObservable.get(),
180+
hideUnlistedTokensObservable,
181+
hideCollectiblesObservable,
182+
fiatCurrencyObservable,
183+
selectedWalletsObservable,
184+
selectedNetworksObservable,
185+
selectedCollectionsObservable,
149186
setFiatCurrency,
150187
setHideCollectibles,
151188
setHideUnlistedTokens,

packages/react-wallet/src/utils/tokens.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { TokenPrice } from '@0xsequence/api'
22
import { TokenBalance, GetTransactionHistoryReturn, Transaction } from '@0xsequence/indexer'
33
import { compareAddress } from '@0xsequence/react-connect'
4-
import { InfiniteData } from '@tanstack/react-query'
4+
import { InfiniteData, useInfiniteQuery } from '@tanstack/react-query'
55
import { ethers } from 'ethers'
66

77
export const getPercentageColor = (value: number) => {
@@ -96,3 +96,21 @@ export const flattenPaginatedTransactionHistory = (
9696

9797
return transactionHistory
9898
}
99+
100+
export const getMoreBalances = (balances: TokenBalance[], pageSize: number, options?: { enabled: boolean }) => {
101+
return useInfiniteQuery({
102+
queryKey: ['infiniteBalances', balances],
103+
queryFn: ({ pageParam }) => {
104+
const startIndex = pageParam * pageSize
105+
return balances.slice(startIndex, startIndex + pageSize)
106+
},
107+
getNextPageParam: (lastPage, allPages) => {
108+
if (lastPage.length < pageSize) {
109+
return undefined
110+
}
111+
return allPages.length
112+
},
113+
initialPageParam: 0,
114+
enabled: !!balances.length && (options?.enabled ?? true)
115+
})
116+
}

0 commit comments

Comments
 (0)