Skip to content

Commit

Permalink
Merge pull request #5433 from EdgeApp/jon/tx-list-chart
Browse files Browse the repository at this point in the history
Jon/tx-list-chart
  • Loading branch information
Jon-edge authored Jan 29, 2025
2 parents 3c7a1e9 + f50c090 commit 380d100
Show file tree
Hide file tree
Showing 19 changed files with 518 additions and 104 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
## Unreleased (develop)

- added: Search bar to `EarnScene`
- added: Price chart to `TransactionListScene`
- added: Add Unizen DEX
- changed: `TransactionListScene` split into two scenes: `TransactionListScene` and `TransactionListScene2`

## 4.21.1 (2025-01-28)

Expand Down
4 changes: 2 additions & 2 deletions src/actions/WalletListMenuActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export type WalletListMenuKey =
| string // for split keys like splitbitcoincash, splitethereum, etc.

export function walletListMenuAction(
navigation: WalletsTabSceneProps<'walletList' | 'transactionList'>['navigation'],
navigation: WalletsTabSceneProps<'walletList' | 'walletDetails'>['navigation'],
walletId: string,
option: WalletListMenuKey,
tokenId: EdgeTokenId,
Expand Down Expand Up @@ -292,7 +292,7 @@ export function walletListMenuAction(
const { currencyWallets } = account
const wallet = currencyWallets[walletId]

navigation.navigate('transactionList', {
navigation.navigate('walletDetails', {
walletId,
tokenId: null,
walletName: getWalletName(wallet)
Expand Down
3 changes: 2 additions & 1 deletion src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { changeTheme, getTheme } from './components/services/ThemeContext'
import { ENV } from './env'
import { NumberMap } from './types/types'
import { log, logToServer } from './util/logger'
import { initInfoServer } from './util/network'
import { initCoinrankList, initInfoServer } from './util/network'

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

Expand Down Expand Up @@ -278,5 +278,6 @@ if (ENV.DEBUG_THEME) {

initDeviceSettings().catch(err => console.log(err))
initInfoServer().catch(err => console.log(err))
initCoinrankList().catch(err => console.log(err))

if (global.Buffer == null) global.Buffer = Buffer
18 changes: 17 additions & 1 deletion src/components/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,10 @@ import { SweepPrivateKeyCompletionScene as SweepPrivateKeyCompletionSceneCompone
import { SweepPrivateKeyProcessingScene as SweepPrivateKeyProcessingSceneComponent } from './scenes/SweepPrivateKeyProcessingScene'
import { SweepPrivateKeySelectCryptoScene as SweepPrivateKeySelectCryptoSceneComponent } from './scenes/SweepPrivateKeySelectCryptoScene'
import { TransactionDetailsScene as TransactionDetailsSceneComponent } from './scenes/TransactionDetailsScene'
import { TransactionList as TransactionListComponent } from './scenes/TransactionListScene'
import { TransactionList as TransactionListComponent } from './scenes/TransactionListScene2'
import { TransactionsExportScene as TransactionsExportSceneComponent } from './scenes/TransactionsExportScene'
import { UpgradeUsernameScene as UpgradeUsernameSceneComponent } from './scenes/UpgradeUsernameScreen'
import { WalletDetails as WalletDetailsComponent } from './scenes/WalletDetailsScene'
import { WalletListScene as WalletListSceneComponent } from './scenes/WalletListScene'
import { WalletRestoreScene as WalletRestoreSceneComponent } from './scenes/WalletRestoreScene'
import { WcConnectionsScene as WcConnectionsSceneComponent } from './scenes/WcConnectionsScene'
Expand Down Expand Up @@ -218,6 +219,7 @@ const SwapSettingsScene = ifLoggedIn(SwapSettingsSceneComponent)
const SwapSuccessScene = ifLoggedIn(SwapSuccessSceneComponent)
const TransactionDetailsScene = ifLoggedIn(TransactionDetailsSceneComponent)
const TransactionList = ifLoggedIn(TransactionListComponent)
const WalletDetails = ifLoggedIn(WalletDetailsComponent)
const TransactionsExportScene = ifLoggedIn(TransactionsExportSceneComponent)
const WalletListScene = ifLoggedIn(WalletListSceneComponent)
const WalletRestoreScene = ifLoggedIn(WalletRestoreSceneComponent)
Expand Down Expand Up @@ -276,6 +278,13 @@ const EdgeWalletsTabScreen = () => {
headerTitle: () => <ParamHeaderTitle<'transactionList'> fromParams={params => params.walletName} />
}}
/>
<WalletsStack.Screen
name="walletDetails"
component={WalletDetails}
options={{
headerTitle: () => <ParamHeaderTitle<'walletDetails'> fromParams={params => params.walletName} />
}}
/>
</WalletsStack.Navigator>
)
}
Expand Down Expand Up @@ -781,6 +790,13 @@ const EdgeAppStack = () => {
headerTitle: () => <TransactionDetailsTitle />
}}
/>
<WalletsStack.Screen
name="transactionList"
component={TransactionList}
options={{
headerTitle: () => <ParamHeaderTitle<'transactionList'> fromParams={params => params.walletName} />
}}
/>
<AppStack.Screen
name="transactionsExport"
component={TransactionsExportScene}
Expand Down
2 changes: 1 addition & 1 deletion src/components/cards/VisaCardCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const ioniaPluginIds = Object.keys(SPECIAL_CURRENCY_INFO).filter(pluginId
interface Props {
wallet: EdgeCurrencyWallet
tokenId: EdgeTokenId
navigation: WalletsTabSceneProps<'transactionList'>['navigation']
navigation: WalletsTabSceneProps<'walletDetails'>['navigation']
}

export const VisaCardCard = (props: Props) => {
Expand Down
16 changes: 13 additions & 3 deletions src/components/charts/SwipeChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { formatFiatString } from '../../hooks/useFiatText'
import { useHandler } from '../../hooks/useHandler'
import { formatDate } from '../../locales/intl'
import { lstrings } from '../../locales/strings'
import { fixSides, mapSides, sidesToMargin } from '../../util/sides'
import { MinimalButton } from '../buttons/MinimalButton'
import { FillLoader } from '../progress-indicators/FillLoader'
import { showWarning } from '../services/AirshipInstance'
Expand All @@ -25,9 +26,16 @@ type Timespan = 'year' | 'month' | 'week' | 'day' | 'hour'
type CoinGeckoDataPair = number[]

interface Props {
assetId: string // The asset's 'id' as defined by CoinGecko
/** The asset's 'id' as defined by CoinGecko */
assetId: string
currencyCode: string
fiatCurrencyCode: string
/**
* Typically we don't want to add custom margins to break consistent design,
* but for this particular component, we sometimes want to adjust how the line
* chart itself, minus the timeframe buttons, is laid out.
*/
marginRem?: number[] | number
}
interface ChartDataPoint {
x: Date
Expand Down Expand Up @@ -129,7 +137,9 @@ const reduceChartData = (chartData: ChartDataPoint[], timespan: Timespan): Chart
const SwipeChartComponent = (params: Props) => {
const theme = useTheme()
const styles = getStyles(theme)
const { assetId, currencyCode, fiatCurrencyCode } = params
const { assetId, marginRem, currencyCode, fiatCurrencyCode } = params

const customMargin = sidesToMargin(mapSides(fixSides(marginRem, 0), theme.rem))

// #region Chart setup

Expand Down Expand Up @@ -567,7 +577,7 @@ const SwipeChartComponent = (params: Props) => {
toolTipProps={tooltipProps}
// #endregion ToolTip

style={styles.baseChart}
style={[styles.baseChart, customMargin]}
/>

{/* Min/Max price labels */}
Expand Down
4 changes: 3 additions & 1 deletion src/components/common/SectionHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ export const SectionHeader = (props: Props) => {
const getStyles = cacheStyles((theme: Theme) => ({
leftColumn: {
flexDirection: 'column',
justifyContent: 'flex-start'
justifyContent: 'flex-start',
flexShrink: 1,
marginRight: theme.rem(1)
},
rightColumn: {
flexDirection: 'column',
Expand Down
2 changes: 1 addition & 1 deletion src/components/modals/WalletListMenuModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ interface Option {

interface Props {
bridge: AirshipBridge<void>
navigation: WalletsTabSceneProps<'walletList' | 'transactionList'>['navigation']
navigation: WalletsTabSceneProps<'walletList' | 'walletDetails'>['navigation']

// Wallet identity:
tokenId: EdgeTokenId
Expand Down
64 changes: 45 additions & 19 deletions src/components/scenes/CoinRankingDetailsScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import * as React from 'react'
import { View } from 'react-native'
import FastImage from 'react-native-fast-image'

import { useAsyncValue } from '../../hooks/useAsyncValue'
import { formatFiatString } from '../../hooks/useFiatText'
import { toLocaleDate, toPercentString } from '../../locales/intl'
import { lstrings } from '../../locales/strings'
import { getDefaultFiat } from '../../selectors/SettingsSelectors'
import { CoinRankingData, CoinRankingDataPercentChange } from '../../types/coinrankTypes'
import { asCoinRankingData, CoinRankingData, CoinRankingDataPercentChange } from '../../types/coinrankTypes'
import { useSelector } from '../../types/reactRedux'
import { EdgeAppSceneProps } from '../../types/routerTypes'
import { fetchRates } from '../../util/network'
import { formatLargeNumberString as formatLargeNumber } from '../../util/utils'
import { SwipeChart } from '../charts/SwipeChart'
import { EdgeAnim, fadeInLeft } from '../common/EdgeAnim'
Expand All @@ -21,7 +23,8 @@ import { COINGECKO_SUPPORTED_FIATS } from './CoinRankingScene'
type CoinRankingDataValueType = string | number | CoinRankingDataPercentChange | undefined

export interface CoinRankingDetailsParams {
coinRankingData: CoinRankingData
assetId?: string
coinRankingData?: CoinRankingData
fiatCurrencyCode: string
}

Expand Down Expand Up @@ -79,14 +82,33 @@ const CoinRankingDetailsSceneComponent = (props: Props) => {
const theme = useTheme()
const styles = getStyles(theme)
const { route, navigation } = props
const { coinRankingData, fiatCurrencyCode } = route.params
const { currencyCode, currencyName } = coinRankingData
const currencyCodeUppercase = currencyCode.toUpperCase()
const { assetId, fiatCurrencyCode, coinRankingData: initCoinRankingData } = route.params

// In case the user changes their default fiat while viewing this scene, we
// want to go back since the parent scene handles fetching data.
const defaultFiat = useSelector(state => getDefaultFiat(state))
const supportedFiat = COINGECKO_SUPPORTED_FIATS[defaultFiat as keyof typeof COINGECKO_SUPPORTED_FIATS] != null ? defaultFiat : 'USD'
const [fetchedCoinRankingData] = useAsyncValue(async () => {
if (assetId == null) {
throw new Error('No currencyCode or coinRankingData provided')
}
const response = await fetchRates(`v2/coinrankAsset/${assetId}?fiatCode=iso:${supportedFiat}`)
if (!response.ok) {
const text = await response.text()
throw new Error(`Unable to fetch coin ranking data. ${text}`)
}

const json = await response.json()
const crData = asCoinRankingData(json.data)

return crData
}, [assetId, supportedFiat])

const coinRankingData = fetchedCoinRankingData ?? initCoinRankingData

const { currencyCode, currencyName } = coinRankingData ?? {}
const currencyCodeUppercase = currencyCode?.toUpperCase() ?? ''

const isFocused = useIsFocused()
const initFiat = React.useState<string>(fiatCurrencyCode)[0]
React.useEffect(() => {
Expand All @@ -100,7 +122,7 @@ const CoinRankingDetailsSceneComponent = (props: Props) => {

const imageUrlObject = React.useMemo(
() => ({
uri: coinRankingData.imageUrl ?? ''
uri: coinRankingData?.imageUrl ?? ''
}),
[coinRankingData]
)
Expand Down Expand Up @@ -140,19 +162,19 @@ const CoinRankingDetailsSceneComponent = (props: Props) => {
case 'rank':
return `#${baseString}`
case 'marketCapChange24h':
extendedString = coinRankingData.marketCapChangePercent24h != null ? ` (${toPercentString(coinRankingData.marketCapChangePercent24h / 100)})` : ''
extendedString = coinRankingData?.marketCapChangePercent24h != null ? ` (${toPercentString(coinRankingData.marketCapChangePercent24h / 100)})` : ''
break
case 'allTimeHigh': {
const fiatString = `${formatFiatString({
fiatAmount: baseString
})} ${supportedFiat}`
return coinRankingData.allTimeHighDate != null ? `${fiatString} - ${toLocaleDate(new Date(coinRankingData.allTimeHighDate))}` : fiatString
return coinRankingData?.allTimeHighDate != null ? `${fiatString} - ${toLocaleDate(new Date(coinRankingData.allTimeHighDate))}` : fiatString
}
case 'allTimeLow': {
const fiatString = `${formatFiatString({
fiatAmount: baseString
})} ${supportedFiat}`
return coinRankingData.allTimeLowDate != null ? `${fiatString} - ${toLocaleDate(new Date(coinRankingData.allTimeLowDate))}` : fiatString
return coinRankingData?.allTimeLowDate != null ? `${fiatString} - ${toLocaleDate(new Date(coinRankingData.allTimeLowDate))}` : fiatString
}
default:
// If no special modifications, just return simple data formatting
Expand Down Expand Up @@ -194,17 +216,21 @@ const CoinRankingDetailsSceneComponent = (props: Props) => {

return (
<SceneWrapper hasTabs hasNotifications scroll>
<View style={styles.container}>
<EdgeAnim style={styles.titleContainer} enter={fadeInLeft}>
<FastImage style={styles.icon} source={imageUrlObject} />
<EdgeText style={styles.title}>{`${currencyName} (${currencyCodeUppercase})`}</EdgeText>
</EdgeAnim>
<SwipeChart assetId={coinRankingData.assetId} currencyCode={currencyCodeUppercase} fiatCurrencyCode={initFiat} />
<View style={styles.columns}>
<View style={styles.column}>{renderRows(coinRankingData, COLUMN_LEFT_DATA_KEYS)}</View>
<View style={styles.column}>{renderRows(coinRankingData, COLUMN_RIGHT_DATA_KEYS)}</View>
{coinRankingData != null ? (
<View style={styles.container}>
<EdgeAnim style={styles.titleContainer} enter={fadeInLeft}>
<FastImage style={styles.icon} source={imageUrlObject} />
<EdgeText style={styles.title}>{`${currencyName} (${currencyCodeUppercase})`}</EdgeText>
</EdgeAnim>
<SwipeChart assetId={coinRankingData.assetId} currencyCode={currencyCodeUppercase} fiatCurrencyCode={initFiat} />
<View style={styles.columns}>
<View style={styles.column}>{renderRows(coinRankingData, COLUMN_LEFT_DATA_KEYS)}</View>
<View style={styles.column}>{renderRows(coinRankingData, COLUMN_RIGHT_DATA_KEYS)}</View>
</View>
</View>
</View>
) : (
<EdgeText>{lstrings.loading}</EdgeText>
)}
</SceneWrapper>
)
}
Expand Down
Loading

0 comments on commit 380d100

Please sign in to comment.