Skip to content

Commit 65055ef

Browse files
committed
WIP on add charts to txlist
1 parent 411134a commit 65055ef

File tree

4 files changed

+111
-24
lines changed

4 files changed

+111
-24
lines changed

src/app.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { changeTheme, getTheme } from './components/services/ThemeContext'
1717
import { ENV } from './env'
1818
import { NumberMap } from './types/types'
1919
import { log, logToServer } from './util/logger'
20-
import { initInfoServer } from './util/network'
20+
import { initCoinrankList, initInfoServer } from './util/network'
2121

2222
export type Environment = 'development' | 'testing' | 'production'
2323

@@ -278,5 +278,6 @@ if (ENV.DEBUG_THEME) {
278278

279279
initDeviceSettings().catch(err => console.log(err))
280280
initInfoServer().catch(err => console.log(err))
281+
initCoinrankList().catch(err => console.log(err))
281282

282283
if (global.Buffer == null) global.Buffer = Buffer

src/components/scenes/CoinRankingDetailsScene.tsx

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ import * as React from 'react'
33
import { View } from 'react-native'
44
import FastImage from 'react-native-fast-image'
55

6+
import { useAsyncEffect } from '../../hooks/useAsyncEffect'
67
import { formatFiatString } from '../../hooks/useFiatText'
78
import { toLocaleDate, toPercentString } from '../../locales/intl'
89
import { lstrings } from '../../locales/strings'
910
import { getDefaultFiat } from '../../selectors/SettingsSelectors'
10-
import { CoinRankingData, CoinRankingDataPercentChange } from '../../types/coinrankTypes'
11+
import { asCoinRankingData, CoinRankingData, CoinRankingDataPercentChange } from '../../types/coinrankTypes'
1112
import { useSelector } from '../../types/reactRedux'
1213
import { EdgeAppSceneProps } from '../../types/routerTypes'
14+
import { fetchRates } from '../../util/network'
1315
import { formatLargeNumberString as formatLargeNumber } from '../../util/utils'
1416
import { SwipeChart } from '../charts/SwipeChart'
1517
import { EdgeAnim, fadeInLeft } from '../common/EdgeAnim'
@@ -21,7 +23,8 @@ import { COINGECKO_SUPPORTED_FIATS } from './CoinRankingScene'
2123
type CoinRankingDataValueType = string | number | CoinRankingDataPercentChange | undefined
2224

2325
export interface CoinRankingDetailsParams {
24-
coinRankingData: CoinRankingData
26+
assetId?: string
27+
coinRankingData?: CoinRankingData
2528
fiatCurrencyCode: string
2629
}
2730

@@ -79,9 +82,10 @@ const CoinRankingDetailsSceneComponent = (props: Props) => {
7982
const theme = useTheme()
8083
const styles = getStyles(theme)
8184
const { route, navigation } = props
82-
const { coinRankingData, fiatCurrencyCode } = route.params
83-
const { currencyCode, currencyName } = coinRankingData
84-
const currencyCodeUppercase = currencyCode.toUpperCase()
85+
const { assetId, coinRankingData: initCoinRankingData, fiatCurrencyCode } = route.params
86+
const [coinRankingData, setCoinRankingData] = React.useState<CoinRankingData | undefined>(initCoinRankingData)
87+
const { currencyCode, currencyName } = coinRankingData ?? {}
88+
const currencyCodeUppercase = currencyCode?.toUpperCase() ?? ''
8589

8690
// In case the user changes their default fiat while viewing this scene, we
8791
// want to go back since the parent scene handles fetching data.
@@ -98,9 +102,30 @@ const CoinRankingDetailsSceneComponent = (props: Props) => {
98102
}
99103
}, [supportedFiat, initFiat, isFocused, navigation])
100104

105+
useAsyncEffect(
106+
async () => {
107+
if (coinRankingData == null) {
108+
if (assetId == null) {
109+
throw new Error('No currencyCode or coinRankingData provided')
110+
}
111+
const response = await fetchRates(`v2/coinrankAsset/${assetId}?fiatCode=${supportedFiat}`)
112+
if (!response.ok) {
113+
const text = await response.text()
114+
throw new Error(`Unable to fetch coin ranking data. ${text}`)
115+
}
116+
117+
const json = await response.json()
118+
const crData = asCoinRankingData(json.data)
119+
setCoinRankingData(crData)
120+
}
121+
},
122+
[currencyCode, supportedFiat],
123+
'CoinRankingDetailsScene'
124+
)
125+
101126
const imageUrlObject = React.useMemo(
102127
() => ({
103-
uri: coinRankingData.imageUrl ?? ''
128+
uri: coinRankingData?.imageUrl ?? ''
104129
}),
105130
[coinRankingData]
106131
)
@@ -140,19 +165,19 @@ const CoinRankingDetailsSceneComponent = (props: Props) => {
140165
case 'rank':
141166
return `#${baseString}`
142167
case 'marketCapChange24h':
143-
extendedString = coinRankingData.marketCapChangePercent24h != null ? ` (${toPercentString(coinRankingData.marketCapChangePercent24h / 100)})` : ''
168+
extendedString = coinRankingData?.marketCapChangePercent24h != null ? ` (${toPercentString(coinRankingData.marketCapChangePercent24h / 100)})` : ''
144169
break
145170
case 'allTimeHigh': {
146171
const fiatString = `${formatFiatString({
147172
fiatAmount: baseString
148173
})} ${supportedFiat}`
149-
return coinRankingData.allTimeHighDate != null ? `${fiatString} - ${toLocaleDate(new Date(coinRankingData.allTimeHighDate))}` : fiatString
174+
return coinRankingData?.allTimeHighDate != null ? `${fiatString} - ${toLocaleDate(new Date(coinRankingData.allTimeHighDate))}` : fiatString
150175
}
151176
case 'allTimeLow': {
152177
const fiatString = `${formatFiatString({
153178
fiatAmount: baseString
154179
})} ${supportedFiat}`
155-
return coinRankingData.allTimeLowDate != null ? `${fiatString} - ${toLocaleDate(new Date(coinRankingData.allTimeLowDate))}` : fiatString
180+
return coinRankingData?.allTimeLowDate != null ? `${fiatString} - ${toLocaleDate(new Date(coinRankingData.allTimeLowDate))}` : fiatString
156181
}
157182
default:
158183
// If no special modifications, just return simple data formatting
@@ -194,17 +219,21 @@ const CoinRankingDetailsSceneComponent = (props: Props) => {
194219

195220
return (
196221
<SceneWrapper hasTabs hasNotifications scroll>
197-
<View style={styles.container}>
198-
<EdgeAnim style={styles.titleContainer} enter={fadeInLeft}>
199-
<FastImage style={styles.icon} source={imageUrlObject} />
200-
<EdgeText style={styles.title}>{`${currencyName} (${currencyCodeUppercase})`}</EdgeText>
201-
</EdgeAnim>
202-
<SwipeChart assetId={coinRankingData.assetId} currencyCode={currencyCodeUppercase} fiatCurrencyCode={initFiat} />
203-
<View style={styles.columns}>
204-
<View style={styles.column}>{renderRows(coinRankingData, COLUMN_LEFT_DATA_KEYS)}</View>
205-
<View style={styles.column}>{renderRows(coinRankingData, COLUMN_RIGHT_DATA_KEYS)}</View>
222+
{coinRankingData != null ? (
223+
<View style={styles.container}>
224+
<EdgeAnim style={styles.titleContainer} enter={fadeInLeft}>
225+
<FastImage style={styles.icon} source={imageUrlObject} />
226+
<EdgeText style={styles.title}>{`${currencyName} (${currencyCodeUppercase})`}</EdgeText>
227+
</EdgeAnim>
228+
<SwipeChart assetId={coinRankingData.assetId} currencyCode={currencyCodeUppercase} fiatCurrencyCode={initFiat} />
229+
<View style={styles.columns}>
230+
<View style={styles.column}>{renderRows(coinRankingData, COLUMN_LEFT_DATA_KEYS)}</View>
231+
<View style={styles.column}>{renderRows(coinRankingData, COLUMN_RIGHT_DATA_KEYS)}</View>
232+
</View>
206233
</View>
207-
</View>
234+
) : (
235+
<EdgeText>Loading...</EdgeText>
236+
)}
208237
</SceneWrapper>
209238
)
210239
}

src/components/scenes/TransactionListScene.tsx

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,18 @@ import { FooterRender } from '../../state/SceneFooterState'
1818
import { useSceneScrollHandler } from '../../state/SceneScrollState'
1919
import { useDispatch, useSelector } from '../../types/reactRedux'
2020
import { NavigationBase, WalletsTabSceneProps } from '../../types/routerTypes'
21-
import { infoServerData } from '../../util/network'
21+
import { coinrankListData, infoServerData } from '../../util/network'
2222
import { calculateSpamThreshold, darkenHexColor, unixToLocaleDateTime, zeroString } from '../../util/utils'
2323
import { InfoCardCarousel } from '../cards/InfoCardCarousel'
24+
import { SwipeChart } from '../charts/SwipeChart'
2425
import { AccentColors } from '../common/DotsBackground'
2526
import { EdgeAnim, fadeInDown10, MAX_LIST_ITEMS_ANIM } from '../common/EdgeAnim'
27+
import { EdgeTouchableOpacity } from '../common/EdgeTouchableOpacity'
2628
import { SceneWrapper } from '../common/SceneWrapper'
2729
import { withWallet } from '../hoc/withWallet'
2830
import { cacheStyles, useTheme } from '../services/ThemeContext'
2931
import { BuyCrypto } from '../themed/BuyCrypto'
32+
import { EdgeText } from '../themed/EdgeText'
3033
import { ExplorerCard } from '../themed/ExplorerCard'
3134
import { SearchFooter } from '../themed/SearchFooter'
3235
import { EmptyLoader, SectionHeader, SectionHeaderCentered } from '../themed/TransactionListComponents'
@@ -66,6 +69,7 @@ function TransactionListComponent(props: Props) {
6669

6770
// Selectors:
6871
const exchangeDenom = getExchangeDenomByCurrencyCode(wallet.currencyConfig, currencyCode)
72+
const fiatCurrencyCode = useSelector(state => state.ui.settings.defaultIsoFiat).replace('iso:', '')
6973
const exchangeRate = useSelector(state => state.exchangeRates[`${currencyCode}_${state.ui.settings.defaultIsoFiat}`])
7074
const spamFilterOn = useSelector(state => state.ui.settings.spamFilterOn)
7175
const activeUsername = useSelector(state => state.core.account.username)
@@ -202,6 +206,12 @@ function TransactionListComponent(props: Props) {
202206
)
203207
}, [])
204208

209+
const assetId = coinrankListData.coins[currencyCode]
210+
211+
const handlePressCoinRanking = useHandler(() => {
212+
navigation.navigate('coinRankingDetails', { assetId, fiatCurrencyCode })
213+
})
214+
205215
const topArea = React.useMemo(() => {
206216
return (
207217
<>
@@ -222,9 +232,29 @@ function TransactionListComponent(props: Props) {
222232
countryCode={route.params.countryCode}
223233
screenWidth={screenWidth}
224234
/>
235+
{assetId != null && (
236+
<EdgeTouchableOpacity onPress={handlePressCoinRanking}>
237+
<EdgeText>See More</EdgeText>
238+
</EdgeTouchableOpacity>
239+
)}
240+
{assetId != null && <SwipeChart assetId={assetId} currencyCode={currencyCode} fiatCurrencyCode={fiatCurrencyCode} />}
225241
</>
226242
)
227-
}, [listItems.length, navigation, isSearching, tokenId, wallet, isLightAccount, pluginId, route.params.countryCode, screenWidth])
243+
}, [
244+
listItems.length,
245+
navigation,
246+
isSearching,
247+
tokenId,
248+
wallet,
249+
isLightAccount,
250+
pluginId,
251+
route.params.countryCode,
252+
screenWidth,
253+
assetId,
254+
currencyCode,
255+
fiatCurrencyCode,
256+
handlePressCoinRanking
257+
])
228258

229259
const emptyComponent = React.useMemo(() => {
230260
if (isTransactionListUnsupported) {

src/util/network.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Cleaner } from 'cleaners'
1+
import { asObject, asString, Cleaner } from 'cleaners'
22
import { EdgeFetchFunction, EdgeFetchOptions, EdgeFetchResponse } from 'edge-core-js'
33
import { asInfoRollup, InfoRollup } from 'edge-info-server'
44
import { Platform } from 'react-native'
@@ -7,7 +7,8 @@ import { getVersion } from 'react-native-device-info'
77
import { config } from '../theme/appConfig'
88
import { asyncWaterfall, getOsVersion, shuffleArray } from './utils'
99
const INFO_SERVERS = ['https://info1.edge.app', 'https://info2.edge.app']
10-
const RATES_SERVERS = ['https://rates1.edge.app', 'https://rates2.edge.app']
10+
// const RATES_SERVERS = ['https://rates1.edge.app', 'https://rates2.edge.app']
11+
const RATES_SERVERS = ['http://localhost:8008']
1112

1213
const INFO_FETCH_INTERVAL = 5 * 60 * 1000 // 5 minutes
1314

@@ -96,3 +97,29 @@ export const initInfoServer = async () => {
9697
await queryInfo()
9798
setInterval(queryInfo, INFO_FETCH_INTERVAL)
9899
}
100+
101+
const asCoinrankList = asObject(asString)
102+
103+
const asCoinGeckoCoinsResponse = asObject({
104+
data: asCoinrankList
105+
})
106+
107+
export type CoinrankList = ReturnType<typeof asCoinrankList>
108+
109+
export const coinrankListData: { coins: CoinrankList } = { coins: {} }
110+
export const initCoinrankList = async () => {
111+
try {
112+
const response = await fetchRates('v2/coinrankList')
113+
if (!response.ok) {
114+
const text = await response.text()
115+
throw new Error(`initCoinrankList error ${response.status}: ${text}`)
116+
}
117+
const responseJson = await response.json()
118+
const { data } = asCoinGeckoCoinsResponse(responseJson)
119+
120+
coinrankListData.coins = data
121+
console.log('initCoinrankList: Successfully fetched coingecko list')
122+
} catch (e) {
123+
console.warn('initCoinrankList: Failed to fetch coinrank list', String(e))
124+
}
125+
}

0 commit comments

Comments
 (0)