-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature(wallet-mobile): new tx review stake pool details (#3723)
Signed-off-by: banklesss <[email protected]> Co-authored-by: Juliano Lazzarotto <[email protected]>
- Loading branch information
1 parent
a918442
commit 6a5cda4
Showing
11 changed files
with
714 additions
and
260 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
apps/wallet-mobile/src/features/ReviewTx/common/ExplorerInfoLinks.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import {useTheme} from '@yoroi/theme' | ||
import {Explorers} from '@yoroi/types' | ||
import * as React from 'react' | ||
import {Linking, StyleSheet, Text, TouchableOpacity, View} from 'react-native' | ||
|
||
import {Space} from '../../../components/Space/Space' | ||
import {useSelectedWallet} from '../../WalletManager/common/hooks/useSelectedWallet' | ||
import {useStrings} from './hooks/useStrings' | ||
|
||
export const ExplorerInfoLinks = ({id, type}: {id: string; type: 'token' | 'pool'}) => { | ||
const {styles} = useStyles() | ||
const {wallet} = useSelectedWallet() | ||
const strings = useStrings() | ||
|
||
const handleOpenLink = async (explorer: Explorers.Explorer) => { | ||
if (id == null) return | ||
if (explorer === Explorers.Explorer.CardanoScan) { | ||
await Linking.openURL(wallet.networkManager.explorers.cardanoscan[type](id)) | ||
} else { | ||
await Linking.openURL(wallet.networkManager.explorers.cexplorer[type](id)) | ||
} | ||
} | ||
|
||
return ( | ||
<View> | ||
<Space width="sm" /> | ||
|
||
<Text style={styles.label}>{strings.details}</Text> | ||
|
||
<View style={styles.linkGroup}> | ||
<TouchableOpacity onPress={() => handleOpenLink(Explorers.Explorer.CardanoScan)}> | ||
<Text style={styles.link}>{explorerNames[Explorers.Explorer.CardanoScan]}</Text> | ||
</TouchableOpacity> | ||
|
||
<TouchableOpacity onPress={() => handleOpenLink(Explorers.Explorer.CExplorer)}> | ||
<Text style={styles.link}>{explorerNames[Explorers.Explorer.CExplorer]}</Text> | ||
</TouchableOpacity> | ||
</View> | ||
</View> | ||
) | ||
} | ||
|
||
const explorerNames = { | ||
[Explorers.Explorer.CardanoScan]: 'Cardanoscan', | ||
[Explorers.Explorer.CExplorer]: 'Adaex', | ||
} | ||
|
||
const useStyles = () => { | ||
const {atoms, color} = useTheme() | ||
|
||
const styles = StyleSheet.create({ | ||
label: { | ||
...atoms.body_2_md_regular, | ||
color: color.text_gray_low, | ||
}, | ||
link: { | ||
...atoms.link_1_lg_underline, | ||
color: color.text_primary_medium, | ||
}, | ||
linkGroup: { | ||
...atoms.flex_row, | ||
...atoms.gap_lg, | ||
}, | ||
}) | ||
|
||
const colors = { | ||
copy: color.gray_900, | ||
} | ||
|
||
return {styles, colors} as const | ||
} |
215 changes: 215 additions & 0 deletions
215
apps/wallet-mobile/src/features/ReviewTx/common/PoolDetails.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,215 @@ | ||
import {FullPoolInfo} from '@emurgo/yoroi-lib' | ||
import {useTheme} from '@yoroi/theme' | ||
import {Image} from 'expo-image' | ||
import * as React from 'react' | ||
import {StyleSheet, Text, View} from 'react-native' | ||
import {ScrollView} from 'react-native-gesture-handler' | ||
|
||
import {Space} from '../../../components/Space/Space' | ||
import {isEmptyString} from '../../../kernel/utils' | ||
import {formatTokenWithText} from '../../../yoroi-wallets/utils/format' | ||
import {asQuantity, Quantities} from '../../../yoroi-wallets/utils/utils' | ||
import {useSelectedWallet} from '../../WalletManager/common/hooks/useSelectedWallet' | ||
import {CopiableText} from './CopiableText' | ||
import {ExplorerInfoLinks} from './ExplorerInfoLinks' | ||
import {useStrings} from './hooks/useStrings' | ||
import {generatePoolName} from './operations' | ||
|
||
export const PoolDetails = ({poolInfo}: {poolInfo: FullPoolInfo}) => { | ||
const {styles} = useStyles() | ||
const strings = useStrings() | ||
const {wallet} = useSelectedWallet() | ||
|
||
const {chain, explorer} = poolInfo | ||
|
||
const lastChainPoolInfo = chain?.history.at(-1) ?? null | ||
const poolName = generatePoolName(poolInfo) | ||
|
||
return ( | ||
<ScrollView bounces={false} style={styles.root}> | ||
<PoolIcon imageUrl={explorer?.pic} /> | ||
|
||
<Space height="sm" /> | ||
|
||
<Row> | ||
<Text style={styles.title}>{poolName}</Text> | ||
</Row> | ||
|
||
<Space height="xl" /> | ||
|
||
<PoolId poolId={explorer?.id} /> | ||
|
||
<Space height="lg" /> | ||
|
||
<PoolHash poolHash={explorer?.hash} /> | ||
|
||
<Space height="lg" /> | ||
|
||
<Info | ||
label={strings.poolSize} | ||
value={formatTokenWithText(asQuantity(explorer?.stake ?? Quantities.zero), wallet.portfolioPrimaryTokenInfo)} | ||
/> | ||
|
||
<Space height="sm" /> | ||
|
||
<Info label={strings.poolRoa} value={`${explorer?.roa ?? '-'}%`} /> | ||
|
||
<Space height="sm" /> | ||
|
||
<Info label={strings.poolShare} value={`${explorer?.share ?? '-'}%`} /> | ||
|
||
<Space height="sm" /> | ||
|
||
<Info label={strings.poolSaturation} value={`${explorer?.saturation ?? '-'}%`} /> | ||
|
||
<Space height="sm" /> | ||
|
||
<Info | ||
label={strings.poolTaxFix} | ||
value={formatTokenWithText(asQuantity(explorer?.taxFix ?? Quantities.zero), wallet.portfolioPrimaryTokenInfo)} | ||
/> | ||
|
||
<Space width="sm" /> | ||
|
||
<Info label={strings.poolTaxRatio} value={`${explorer?.taxRatio ?? '-'}%`} /> | ||
|
||
<Space width="sm" /> | ||
|
||
<Info | ||
label={strings.poolPledge} | ||
value={formatTokenWithText( | ||
asQuantity( | ||
(lastChainPoolInfo?.payload as {poolParams: {pledge: string}})?.['poolParams']?.['pledge'] ?? | ||
Quantities.zero, | ||
), | ||
wallet.portfolioPrimaryTokenInfo, | ||
)} | ||
/> | ||
|
||
<Space height="lg" /> | ||
|
||
{poolInfo.explorer && !isEmptyString(poolInfo.explorer.id) && ( | ||
<ExplorerInfoLinks id={poolInfo.explorer.id} type="pool" /> | ||
)} | ||
</ScrollView> | ||
) | ||
} | ||
|
||
const PoolIcon = ({imageUrl}: {imageUrl: string | null | undefined}) => { | ||
const {styles} = useStyles() | ||
|
||
if (imageUrl == null) return null | ||
|
||
return ( | ||
<View style={styles.imageContainer}> | ||
<Image source={{uri: imageUrl}} style={styles.image} /> | ||
</View> | ||
) | ||
} | ||
|
||
const PoolId = ({poolId}: {poolId: string | undefined}) => { | ||
const {styles} = useStyles() | ||
const strings = useStrings() | ||
|
||
if (isEmptyString(poolId)) return null | ||
|
||
return ( | ||
<Row> | ||
<Text style={styles.label}>{strings.poolId}</Text> | ||
|
||
<Space width="lg" /> | ||
|
||
<View style={styles.copiableText}> | ||
<CopiableText textToCopy={poolId}> | ||
<Text style={styles.value}>{poolId}</Text> | ||
</CopiableText> | ||
</View> | ||
</Row> | ||
) | ||
} | ||
const PoolHash = ({poolHash}: {poolHash?: string}) => { | ||
const {styles} = useStyles() | ||
const strings = useStrings() | ||
|
||
if (isEmptyString(poolHash)) return null | ||
|
||
return ( | ||
<Row> | ||
<Text style={styles.label}>{strings.poolHash}</Text> | ||
|
||
<Space width="lg" /> | ||
|
||
<View style={styles.copiableText}> | ||
<CopiableText textToCopy={poolHash}> | ||
<Text style={styles.value}>{poolHash}</Text> | ||
</CopiableText> | ||
</View> | ||
</Row> | ||
) | ||
} | ||
|
||
const Info = ({label, value}: {label: string; value?: string}) => { | ||
const {styles} = useStyles() | ||
|
||
if (isEmptyString(value)) return null | ||
|
||
return ( | ||
<Row> | ||
<Text style={styles.label}>{label}</Text> | ||
|
||
<Text style={styles.value}>{value}</Text> | ||
</Row> | ||
) | ||
} | ||
|
||
const Row = ({children}: {children: React.ReactNode}) => { | ||
const {styles} = useStyles() | ||
return <View style={styles.row}>{children}</View> | ||
} | ||
|
||
const useStyles = () => { | ||
const {atoms, color} = useTheme() | ||
|
||
const styles = StyleSheet.create({ | ||
root: { | ||
...atoms.flex_1, | ||
...atoms.px_lg, | ||
}, | ||
imageContainer: { | ||
...atoms.justify_center, | ||
...atoms.align_center, | ||
}, | ||
image: { | ||
width: 80, | ||
height: 80, | ||
}, | ||
label: { | ||
...atoms.body_2_md_regular, | ||
color: color.text_gray_low, | ||
}, | ||
value: { | ||
...atoms.flex_1, | ||
...atoms.text_right, | ||
...atoms.body_2_md_regular, | ||
color: color.text_gray_max, | ||
}, | ||
copiableText: { | ||
...atoms.flex_1, | ||
...atoms.align_center, | ||
}, | ||
row: { | ||
...atoms.flex_row, | ||
...atoms.justify_center, | ||
}, | ||
title: { | ||
color: color.text_gray_medium, | ||
...atoms.body_1_lg_medium, | ||
}, | ||
}) | ||
|
||
const colors = { | ||
copy: color.gray_900, | ||
} | ||
|
||
return {styles, colors} as const | ||
} |
Oops, something went wrong.