From a29ebbd8976bf4e037279e2a43e682f0787d1642 Mon Sep 17 00:00:00 2001 From: Paul Puey Date: Wed, 10 Jan 2024 17:07:58 -0800 Subject: [PATCH] Add iconcolor gradient to send, request, earn, and txdetails --- .../__snapshots__/RequestScene.test.tsx.snap | 27 + .../__snapshots__/SendScene2.ui.test.tsx.snap | 490 +----------------- .../TransactionDetailsScene.test.tsx.snap | 98 +--- src/components/scenes/RequestScene.tsx | 46 +- src/components/scenes/SendScene2.tsx | 22 +- .../scenes/Staking/StakeOptionsScene.tsx | 19 +- .../scenes/TransactionDetailsScene.tsx | 26 +- src/hooks/useIconColor.ts | 40 ++ 8 files changed, 191 insertions(+), 577 deletions(-) create mode 100644 src/hooks/useIconColor.ts diff --git a/src/__tests__/scenes/__snapshots__/RequestScene.test.tsx.snap b/src/__tests__/scenes/__snapshots__/RequestScene.test.tsx.snap index 20daecd4eb3..d9762bf4190 100644 --- a/src/__tests__/scenes/__snapshots__/RequestScene.test.tsx.snap +++ b/src/__tests__/scenes/__snapshots__/RequestScene.test.tsx.snap @@ -2,7 +2,34 @@ exports[`Request should render with loaded props 1`] = ` - - @@ -1193,13 +1148,13 @@ exports[`SendScene2 1 spendTarget with info tiles 1`] = ` - - @@ -2557,13 +2467,13 @@ exports[`SendScene2 2 spendTargets 1`] = ` - - @@ -3906,13 +3771,13 @@ exports[`SendScene2 2 spendTargets hide tiles 1`] = ` - - @@ -5096,13 +4916,13 @@ exports[`SendScene2 2 spendTargets hide tiles 2`] = ` - - @@ -6264,13 +6039,13 @@ exports[`SendScene2 2 spendTargets hide tiles 3`] = ` - - @@ -7273,13 +7003,13 @@ exports[`SendScene2 2 spendTargets lock tiles 1`] = ` - - @@ -8573,13 +8258,13 @@ exports[`SendScene2 2 spendTargets lock tiles 2`] = ` - - @@ -9800,13 +9440,13 @@ exports[`SendScene2 2 spendTargets lock tiles 3`] = ` - - @@ -10978,13 +10573,13 @@ exports[`SendScene2 Render SendScene 1`] = ` - - diff --git a/src/__tests__/scenes/__snapshots__/TransactionDetailsScene.test.tsx.snap b/src/__tests__/scenes/__snapshots__/TransactionDetailsScene.test.tsx.snap index e23df6f0cad..00db4b9eeb5 100644 --- a/src/__tests__/scenes/__snapshots__/TransactionDetailsScene.test.tsx.snap +++ b/src/__tests__/scenes/__snapshots__/TransactionDetailsScene.test.tsx.snap @@ -5,13 +5,13 @@ exports[`TransactionDetailsScene should render 1`] = ` - - @@ -1744,13 +1699,13 @@ exports[`TransactionDetailsScene should render with negative nativeAmount and fi - - diff --git a/src/components/scenes/RequestScene.tsx b/src/components/scenes/RequestScene.tsx index 4e2f3b967e7..ffb0c4d5a1f 100644 --- a/src/components/scenes/RequestScene.tsx +++ b/src/components/scenes/RequestScene.tsx @@ -12,17 +12,18 @@ import { toggleAccountBalanceVisibility } from '../../actions/LocalSettingsActio import { selectWalletToken } from '../../actions/WalletActions' import { Fontello } from '../../assets/vector' import { getSpecialCurrencyInfo, SPECIAL_CURRENCY_INFO } from '../../constants/WalletAndCurrencyConstants' +import { useIconColor } from '../../hooks/useIconColor' import { lstrings } from '../../locales/strings' import { getDisplayDenomination, getExchangeDenomination } from '../../selectors/DenominationSelectors' import { getExchangeRate } from '../../selectors/WalletSelectors' import { config } from '../../theme/appConfig' -import { connect } from '../../types/reactRedux' +import { connect, useSelector } from '../../types/reactRedux' import { EdgeSceneProps, NavigationBase } from '../../types/routerTypes' import { GuiCurrencyInfo } from '../../types/types' -import { getTokenIdForced, isKeysOnlyPlugin } from '../../util/CurrencyInfoHelpers' +import { getTokenId, getTokenIdForced, isKeysOnlyPlugin } from '../../util/CurrencyInfoHelpers' import { getAvailableBalance, getWalletName } from '../../util/CurrencyWalletHelpers' import { triggerHaptic } from '../../util/haptic' -import { convertNativeToDenomination, truncateDecimals, zeroString } from '../../util/utils' +import { convertNativeToDenomination, multiplyHexColor, truncateDecimals, zeroString } from '../../util/utils' import { EdgeAnim } from '../common/EdgeAnim' import { SceneWrapper } from '../common/SceneWrapper' import { AddressModal } from '../modals/AddressModal' @@ -41,6 +42,7 @@ import { MainButton } from '../themed/MainButton' import { SceneHeader } from '../themed/SceneHeader' import { ShareButtons } from '../themed/ShareButtons' import { CardUi4 } from '../ui4/CardUi4' +import { UpdateDots } from '../ui4/DotsBackground' interface OwnProps extends EdgeSceneProps<'request'> {} @@ -64,6 +66,10 @@ interface CurrencyMinimumPopupState { [pluginId: string]: ModalState } +interface HookProps { + iconColor?: string +} + type Props = StateProps & DispatchProps & OwnProps & ThemeProps interface State { @@ -82,7 +88,7 @@ interface AddressInfo { const inputAccessoryViewID: string = 'cancelHeaderId' -export class RequestSceneComponent extends React.Component { +export class RequestSceneComponent extends React.Component { flipInputRef: React.RefObject unsubscribeAddressChanged: (() => void) | undefined @@ -286,7 +292,7 @@ export class RequestSceneComponent extends React.Component { } render() { - const { currencyCode, exchangeSecondaryToPrimaryRatio, wallet, primaryCurrencyInfo, theme } = this.props + const { currencyCode, exchangeSecondaryToPrimaryRatio, iconColor, wallet, primaryCurrencyInfo, theme } = this.props const styles = getStyles(theme) if (currencyCode == null || primaryCurrencyInfo == null || exchangeSecondaryToPrimaryRatio == null || wallet == null) { @@ -307,10 +313,23 @@ export class RequestSceneComponent extends React.Component { // Selected denomination const denomString = `1 ${primaryCurrencyInfo.displayDenomination.name}` + // Change the second dot color and remove the 3rd dot + const overrideDots: UpdateDots = [undefined, { color: iconColor }, null] + const backgroundColors = [...theme.assetBackgroundGradientColors] + if (iconColor != null) { + backgroundColors[0] = multiplyHexColor(iconColor, theme.assetBackgroundColorScale) + } + return keysOnlyMode ? ( this.renderKeysOnlyMode() ) : ( - + {lstrings.fragment_request_subtitle} @@ -539,7 +558,7 @@ const getStyles = cacheStyles((theme: Theme) => ({ } })) -export const RequestScene = connect( +const RequestSceneConnected = connect( state => { const { account } = state.core const { currencyWallets } = account @@ -596,3 +615,16 @@ export const RequestScene = connect( } }) )(withTheme(RequestSceneComponent)) + +export const RequestScene = (props: OwnProps) => { + const account = useSelector(state => state.core.account) + const currencyCode = useSelector(state => state.ui.wallets.selectedCurrencyCode) + const walletId = useSelector(state => state.ui.wallets.selectedWalletId) + const wallet = account.currencyWallets[walletId] ?? {} + + const { pluginId = '' } = wallet.currencyInfo ?? {} + const tokenId = getTokenId(account, pluginId, currencyCode) + + const iconColor = useIconColor({ pluginId, tokenId: tokenId !== undefined ? tokenId : '' }) + return +} diff --git a/src/components/scenes/SendScene2.tsx b/src/components/scenes/SendScene2.tsx index 4875a1e9383..30bb3385526 100644 --- a/src/components/scenes/SendScene2.tsx +++ b/src/components/scenes/SendScene2.tsx @@ -24,6 +24,7 @@ import { useAsyncEffect } from '../../hooks/useAsyncEffect' import { useDisplayDenom } from '../../hooks/useDisplayDenom' import { useExchangeDenom } from '../../hooks/useExchangeDenom' import { useHandler } from '../../hooks/useHandler' +import { useIconColor } from '../../hooks/useIconColor' import { useMount } from '../../hooks/useMount' import { useUnmount } from '../../hooks/useUnmount' import { useWatch } from '../../hooks/useWatch' @@ -37,7 +38,7 @@ import { getCurrencyCode } from '../../util/CurrencyInfoHelpers' import { getWalletName } from '../../util/CurrencyWalletHelpers' import { addToFioAddressCache, checkRecordSendFee, FIO_FEE_EXCEEDS_SUPPLIED_MAXIMUM, FIO_NO_BUNDLED_ERR_CODE, recordSend } from '../../util/FioAddressUtils' import { logActivity } from '../../util/logger' -import { convertTransactionFeeToDisplayFee, DECIMAL_PRECISION, zeroString } from '../../util/utils' +import { convertTransactionFeeToDisplayFee, DECIMAL_PRECISION, multiplyHexColor, zeroString } from '../../util/utils' import { getMemoError, getMemoLabel, getMemoTitle } from '../../util/validateMemos' import { SceneWrapper } from '../common/SceneWrapper' import { styled } from '../hoc/styled' @@ -59,6 +60,7 @@ import { EditableAmountTile } from '../tiles/EditableAmountTile' import { ErrorTile } from '../tiles/ErrorTile' import { AlertCardUi4 } from '../ui4/AlertCardUi4' import { CardUi4 } from '../ui4/CardUi4' +import { UpdateDots } from '../ui4/DotsBackground' import { RowUi4 } from '../ui4/RowUi4' // TODO: Check contentPadding @@ -180,6 +182,7 @@ const SendComponent = (props: Props) => { const cryptoExchangeDenomination = useExchangeDenom(pluginId, currencyCode) const parentDisplayDenom = useDisplayDenom(pluginId, currencyWallets[walletId].currencyInfo.currencyCode) const parentExchangeDenom = useExchangeDenom(pluginId, currencyWallets[walletId].currencyInfo.currencyCode) + const iconColor = useIconColor({ pluginId, tokenId }) spendInfo.tokenId = tokenId @@ -986,8 +989,23 @@ const SendComponent = (props: Props) => { disableSlider = true disabledText = lstrings.spending_limits_enter_pin } + + // Change the second dot color and remove the 3rd dot + const overrideDots: UpdateDots = [undefined, { color: iconColor }, null] + const backgroundColors = [...theme.assetBackgroundGradientColors] + if (iconColor != null) { + backgroundColors[0] = multiplyHexColor(iconColor, theme.assetBackgroundColorScale) + } + return ( - + {({ insetStyles }) => ( <> { wallet: EdgeCurrencyWallet @@ -40,6 +43,7 @@ const StakeOptionsSceneComponent = (props: Props) => { const account = useSelector(state => state.core.account) const pluginId = wallet?.currencyInfo.pluginId const tokenId = pluginId ? getTokenIdForced(account, pluginId, currencyCode) : null + const iconColor = useIconColor({ pluginId, tokenId }) // // Handlers @@ -76,8 +80,21 @@ const StakeOptionsSceneComponent = (props: Props) => { ) } + // Change the second dot color and remove the 3rd dot + const overrideDots: UpdateDots = [undefined, { color: iconColor }, null] + const backgroundColors = [...theme.assetBackgroundGradientColors] + if (iconColor != null) { + backgroundColors[0] = multiplyHexColor(iconColor, theme.assetBackgroundColorScale) + } + return ( - + diff --git a/src/components/scenes/TransactionDetailsScene.tsx b/src/components/scenes/TransactionDetailsScene.tsx index 37bed2d36de..2172de4100a 100644 --- a/src/components/scenes/TransactionDetailsScene.tsx +++ b/src/components/scenes/TransactionDetailsScene.tsx @@ -13,6 +13,7 @@ import { useContactThumbnail } from '../../hooks/redux/useContactThumbnail' import { displayFiatAmount } from '../../hooks/useFiatText' import { useHandler } from '../../hooks/useHandler' import { useHistoricalRate } from '../../hooks/useHistoricalRate' +import { useIconColor } from '../../hooks/useIconColor' import { useWatch } from '../../hooks/useWatch' import { toPercentString } from '../../locales/intl' import { lstrings } from '../../locales/strings' @@ -22,7 +23,7 @@ import { useSelector } from '../../types/reactRedux' import { EdgeSceneProps } from '../../types/routerTypes' import { getCurrencyCodeWithAccount } from '../../util/CurrencyInfoHelpers' import { matchJson } from '../../util/matchJson' -import { convertNativeToExchange } from '../../util/utils' +import { convertNativeToExchange, multiplyHexColor } from '../../util/utils' import { getMemoTitle } from '../../util/validateMemos' import { EdgeAnim } from '../common/EdgeAnim' import { SceneWrapper } from '../common/SceneWrapper' @@ -37,6 +38,7 @@ import { EdgeText } from '../themed/EdgeText' import { AdvancedDetailsCard } from '../ui4/AdvancedDetailsCard' import { ButtonsViewUi4 } from '../ui4/ButtonsViewUi4' import { CardUi4 } from '../ui4/CardUi4' +import { UpdateDots } from '../ui4/DotsBackground' import { RowUi4 } from '../ui4/RowUi4' import { SwapDetailsCard } from '../ui4/SwapDetailsCard' import { TxCryptoAmountRow } from '../ui4/TxCryptoAmountRow' @@ -53,12 +55,14 @@ export interface TransactionDetailsParams { const TransactionDetailsComponent = (props: Props) => { const { navigation, route, wallet } = props const { edgeTransaction: transaction, walletId } = route.params - const { currencyCode, metadata, nativeAmount, date, txid } = transaction + const { currencyCode, metadata, nativeAmount, date, txid, tokenId } = transaction const { currencyInfo } = wallet const theme = useTheme() const account = useSelector(state => state.core.account) const styles = getStyles(theme) + const iconColor = useIconColor({ pluginId: currencyInfo.pluginId, tokenId }) + // Choose a default category based on metadata or the txAction const { direction, iconPluginId, mergedData, savedData } = getTxActionDisplayInfo(transaction, account, wallet) @@ -294,8 +298,24 @@ const TransactionDetailsComponent = (props: Props) => { const categoriesText = formatCategory(splitCategory(localMetadata.category ?? undefined)) + // Change the second dot color and remove the 3rd dot + const overrideDots: UpdateDots = [undefined, { color: iconColor }, null] + const backgroundColors = [...theme.assetBackgroundGradientColors] + if (iconColor != null) { + backgroundColors[0] = multiplyHexColor(iconColor, theme.assetBackgroundColorScale) + } + return ( - + { + const [color, setColor] = useState(undefined) + const primaryCurrencyIconUrl = React.useMemo(() => { + const { pluginId, tokenId } = edgeAsset + if (pluginId == null) return null + + // Get Currency Icon URI + const icon = getCurrencyIconUris(pluginId, tokenId) + return icon.symbolImage + }, [edgeAsset]) + + React.useEffect(() => { + if (primaryCurrencyIconUrl == null) return + + getColors(primaryCurrencyIconUrl, { + cache: true, + key: primaryCurrencyIconUrl + }) + .then(colors => { + if (colors.platform === 'ios') { + setColor(colors.primary) + } + if (colors.platform === 'android') { + setColor(colors.vibrant) + } + }) + .catch(err => { + console.warn(err) + }) + }, [primaryCurrencyIconUrl]) + + return color +}