Skip to content

Commit

Permalink
feat: more actions token bottom sheet
Browse files Browse the repository at this point in the history
  • Loading branch information
MuckT committed Oct 13, 2023
1 parent d977bd6 commit 0df5aac
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 21 deletions.
7 changes: 6 additions & 1 deletion locales/base/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -1845,10 +1845,15 @@
"priceDeltaSuffix": "Today",
"actions": {
"send": "Send",
"sendDetails": "Use any Celo or Ethereum address, domain, phone number, etc.",
"swap": "Swap",
"swapDetails": "Swap your tokens without leaving your wallet",
"add": "Add",
"addDetails": "Buy tokens using one of our trusted providers",
"withdraw": "Withdraw",
"withdrawDetails": "Transfer tokens to a bank account, mobile money, gift card etc.",
"more": "More"
}
},
"moreActions": "More Actions"
}
}
75 changes: 75 additions & 0 deletions src/tokens/MoreActionsBottomSheet.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React, { RefObject } from 'react'
import { useTranslation } from 'react-i18next'
import { StyleSheet, Text, View } from 'react-native'
import BottomSheet, { BottomSheetRefType } from 'src/components/BottomSheet'
import Touchable from 'src/components/Touchable'
import Colors from 'src/styles/colors'
import { typeScale } from 'src/styles/fonts'
import { Spacing } from 'src/styles/styles'
import { useActions } from 'src/tokens/TokenDetails'
import { TokenBalance } from 'src/tokens/slice'

export default function MoreActionsBottomSheet({
forwardedRef,
token,
}: {
forwardedRef: RefObject<BottomSheetRefType>
token: TokenBalance
}) {
const { t } = useTranslation()
const actions = useActions(token)
return (
<BottomSheet
title={t('tokenDetails.moreActions')}
forwardedRef={forwardedRef}
testId="MoreActionsBottomSheet"
>
<View style={styles.actionsContainer}>
{actions.map((action) => {
return (
<View style={styles.actionContainer}>
<Touchable
onPress={action.onPress}
testID={`action/${action.name}`}
borderRadius={20}
style={styles.touchable}
>
<View style={styles.touchableView}>
<action.iconComponent color={Colors.dark} />
<View style={{ flex: 1 }}>
<Text style={styles.actionTitle}>{action.text}</Text>
<Text style={styles.actionDetails}>{action.details}</Text>
</View>
</View>
</Touchable>
</View>
)
})}
</View>
</BottomSheet>
)
}

const styles = StyleSheet.create({
actionsContainer: {
gap: Spacing.Regular16,
},
actionContainer: {
backgroundColor: Colors.gray1,
borderRadius: 20,
},
touchable: {
margin: Spacing.Regular16,
},
touchableView: {
flexDirection: 'row',
gap: Spacing.Regular16,
alignItems: 'center',
},
actionTitle: {
...typeScale.labelMedium,
},
actionDetails: {
...typeScale.bodySmall,
},
})
62 changes: 42 additions & 20 deletions src/tokens/TokenDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { NativeStackScreenProps } from '@react-navigation/native-stack'
import React from 'react'
import React, { useRef } from 'react'
import { useTranslation } from 'react-i18next'
import { ScrollView, StyleSheet, Text, View } from 'react-native'
import { SafeAreaView } from 'react-native-safe-area-context'
import { useSelector } from 'react-redux'
import { AssetsEvents } from 'src/analytics/Events'
import { TokenProperties } from 'src/analytics/Properties'
import ValoraAnalytics from 'src/analytics/ValoraAnalytics'
import { BottomSheetRefType } from 'src/components/BottomSheet'
import Button, { BtnSizes } from 'src/components/Button'
import PercentageIndicator from 'src/components/PercentageIndicator'
import TokenDisplay from 'src/components/TokenDisplay'
Expand All @@ -31,6 +32,7 @@ import { StackParamList } from 'src/navigator/types'
import Colors from 'src/styles/colors'
import { typeScale } from 'src/styles/fonts'
import { Spacing } from 'src/styles/styles'
import MoreActionsBottomSheet from 'src/tokens/MoreActionsBottomSheet'
import { TokenBalanceItem } from 'src/tokens/TokenBalanceItem'
import {
useCashInTokens,
Expand All @@ -52,6 +54,7 @@ export default function TokenDetailsScreen({ route }: Props) {
const { tokenId } = route.params
const { t } = useTranslation()
const token = useTokenInfo(tokenId)
const moreActionsBottomSheetRef = useRef<BottomSheetRefType>(null)

if (!token) {
throw new Error(`token with id ${tokenId} not found`)
Expand Down Expand Up @@ -86,7 +89,7 @@ export default function TokenDetailsScreen({ route }: Props) {
testID="TokenDetails/Chart"
/>
)}
<Actions token={token} />
<Actions token={token} moreActionsBottomSheetRef={moreActionsBottomSheetRef} />
<Text style={styles.yourBalance}>{t('tokenDetails.yourBalance')}</Text>
<TokenBalanceItem token={token} />
{token.infoUrl && (
Expand All @@ -97,6 +100,7 @@ export default function TokenDetailsScreen({ route }: Props) {
/>
)}
</ScrollView>
<MoreActionsBottomSheet forwardedRef={moreActionsBottomSheetRef} token={token} />
</SafeAreaView>
)
}
Expand Down Expand Up @@ -136,7 +140,21 @@ function PriceInfo({ token }: { token: TokenBalance }) {
)
}

function Actions({ token }: { token: TokenBalance }) {
export const onPressCicoAction = (token: TokenBalance, flow: CICOFlow) => {
const tokenSymbol = token.symbol

Check warning on line 144 in src/tokens/TokenDetails.tsx

View check run for this annotation

Codecov / codecov/patch

src/tokens/TokenDetails.tsx#L144

Added line #L144 was not covered by tests
// this should always be true given that we only show Add / Withdraw if a
// token is CiCoCurrency, but adding it here to ensure type safety
if (isCicoToken(tokenSymbol)) {
navigate(Screens.FiatExchangeAmount, {

Check warning on line 148 in src/tokens/TokenDetails.tsx

View check run for this annotation

Codecov / codecov/patch

src/tokens/TokenDetails.tsx#L148

Added line #L148 was not covered by tests
currency: tokenSymbol,
tokenId: token.tokenId,
flow,
network: Network.Celo,
})
}
}

export const useActions = (token: TokenBalance) => {
const { t } = useTranslation()
const sendableTokens = useSendableTokens()
const swappableTokens = useSwappableTokens()
Expand All @@ -145,24 +163,11 @@ function Actions({ token }: { token: TokenBalance }) {
const isSwapEnabled = useSelector(isAppSwapsEnabledSelector)
const showWithdraw = !!cashOutTokens.find((tokenInfo) => tokenInfo.tokenId === token.tokenId)

const onPressCicoAction = (flow: CICOFlow) => {
const tokenSymbol = token.symbol
// this should always be true given that we only show Add / Withdraw if a
// token is CiCoCurrency, but adding it here to ensure type safety
if (isCicoToken(tokenSymbol)) {
navigate(Screens.FiatExchangeAmount, {
currency: tokenSymbol,
tokenId: token.tokenId,
flow,
network: Network.Celo,
})
}
}

const actions = [
return [
{
name: TokenDetailsActionName.Send,
text: t('tokenDetails.actions.send'),
details: t('tokenDetails.actions.sendDetails'),
iconComponent: QuickActionsSend,
onPress: () => {
navigate(Screens.Send, { defaultTokenIdOverride: token.tokenId })
Expand All @@ -172,6 +177,7 @@ function Actions({ token }: { token: TokenBalance }) {
{
name: TokenDetailsActionName.Swap,
text: t('tokenDetails.actions.swap'),
details: t('tokenDetails.actions.swapDetails'),
iconComponent: QuickActionsSwap,
onPress: () => {
navigate(Screens.SwapScreenWithBack, { fromTokenId: token.tokenId })
Expand All @@ -184,29 +190,45 @@ function Actions({ token }: { token: TokenBalance }) {
{
name: TokenDetailsActionName.Add,
text: t('tokenDetails.actions.add'),
details: t('tokenDetails.actions.addDetails'),
iconComponent: QuickActionsAdd,
onPress: () => {
onPressCicoAction(CICOFlow.CashIn)
onPressCicoAction(token, CICOFlow.CashIn)

Check warning on line 196 in src/tokens/TokenDetails.tsx

View check run for this annotation

Codecov / codecov/patch

src/tokens/TokenDetails.tsx#L196

Added line #L196 was not covered by tests
},
visible: !!cashInTokens.find((tokenInfo) => tokenInfo.tokenId === token.tokenId),
},
{
name: TokenDetailsActionName.Withdraw,
text: t('tokenDetails.actions.withdraw'),
details: t('tokenDetails.actions.withdrawDetails'),
iconComponent: QuickActionsWithdraw,
onPress: () => {
onPressCicoAction(CICOFlow.CashOut)
onPressCicoAction(token, CICOFlow.CashOut)

Check warning on line 206 in src/tokens/TokenDetails.tsx

View check run for this annotation

Codecov / codecov/patch

src/tokens/TokenDetails.tsx#L206

Added line #L206 was not covered by tests
},
visible: showWithdraw,
},
].filter((action) => action.visible)
}

function Actions({
token,
moreActionsBottomSheetRef,
}: {
token: TokenBalance
moreActionsBottomSheetRef: React.RefObject<BottomSheetRefType>
}) {
const { t } = useTranslation()
const actions = useActions(token)
const cashOutTokens = useCashOutTokens()
const showWithdraw = !!cashOutTokens.find((tokenInfo) => tokenInfo.tokenId === token.tokenId)

const moreAction = {
name: TokenDetailsActionName.More,
text: t('tokenDetails.actions.more'),
iconComponent: QuickActionsMore,
onPress: () => {
// TODO(ACT-917): open bottom sheet
moreActionsBottomSheetRef.current?.snapToIndex(0)
},
}

Expand Down

0 comments on commit 0df5aac

Please sign in to comment.