diff --git a/src/features/rnbw-staking/screens/rnbw-staking-screen/RnbwStakingScreen.tsx b/src/features/rnbw-staking/screens/rnbw-staking-screen/RnbwStakingScreen.tsx index 17b70fad9b0..abb884dbc47 100644 --- a/src/features/rnbw-staking/screens/rnbw-staking-screen/RnbwStakingScreen.tsx +++ b/src/features/rnbw-staking/screens/rnbw-staking-screen/RnbwStakingScreen.tsx @@ -1,15 +1,34 @@ -import React, { memo, useMemo } from 'react'; +import React, { memo, useCallback, useMemo } from 'react'; +import { StyleSheet } from 'react-native'; +import { RnbwHoldToActivateButton } from '@/features/rnbw-membership/components/RnbwHoldToActivateButton'; import { RNBW_STAKING_DEPOSIT_CONFIG } from '@/features/rnbw-staking/depositConfig'; import { buildSyntheticRnbwSourceAsset } from '@/features/rnbw-staking/utils/syntheticRnbwSourceAsset'; import { DepositScreen } from '@/systems/funding/components/DepositScreen'; +import { type DepositSubmitButtonRenderParams } from '@/systems/funding/types'; export const RnbwStakingScreen = memo(function RnbwStakingScreen() { const syntheticSourceAsset = useMemo(() => buildSyntheticRnbwSourceAsset({ includeRewardsBalance: true }), []); + const renderSubmitButton = useCallback( + ({ disabled, isSubmitting, label, onSubmit }: DepositSubmitButtonRenderParams) => ( + + ), + [] + ); return ( ); }); + +const styles = StyleSheet.create({ + submitButton: { + width: '100%', + }, +}); diff --git a/src/systems/funding/components/DepositScreen.tsx b/src/systems/funding/components/DepositScreen.tsx index fbe22c36913..1673b8cb4c5 100644 --- a/src/systems/funding/components/DepositScreen.tsx +++ b/src/systems/funding/components/DepositScreen.tsx @@ -33,7 +33,13 @@ import { createDepositConfig } from '../config'; import { FOOTER_HEIGHT, NavigationSteps, SLIDER_WIDTH, SLIDER_WITH_LABELS_HEIGHT } from '../constants'; import { DepositProvider, useDepositContext } from '../contexts/DepositContext'; import { computeMaxSwappableAmount } from '../stores/createDepositStore'; -import { type DepositConfigInput, DepositQuoteStatus, type FundingScreenTheme, getAccentColor } from '../types'; +import { + type DepositConfigInput, + DepositQuoteStatus, + type DepositSubmitButtonRenderer, + type FundingScreenTheme, + getAccentColor, +} from '../types'; import { resolveInitialDepositAsset } from '../utils/sourceAsset'; import { amountFromSliderProgress } from '../utils/sliderWorklets'; import { DepositAmountInput } from './deposit/DepositAmountInput'; @@ -46,18 +52,19 @@ import { DepositTokenList } from './deposit/DepositTokenList'; type DepositScreenProps = { config: DepositConfigInput; initialAsset?: ExtendedAnimatedAssetWithColors | null; + renderSubmitButton?: DepositSubmitButtonRenderer; theme: FundingScreenTheme; }; // ============ Main Screen ==================================================== // -export const DepositScreen = memo(function DepositScreen({ config, initialAsset, theme }: DepositScreenProps) { +export const DepositScreen = memo(function DepositScreen({ config, initialAsset, renderSubmitButton, theme }: DepositScreenProps) { const resolvedConfig = useMemo(() => createDepositConfig(config), [config]); const resolvedInitialAsset = useStableValue(() => initialAsset ?? resolveInitialDepositAsset(resolvedConfig)); return ( - + ); }); @@ -78,7 +85,11 @@ function getInputAmountError( // ============ Screen Content ================================================= // -const DepositScreenContent = memo(function DepositScreenContent() { +const DepositScreenContent = memo(function DepositScreenContent({ + renderSubmitButton, +}: { + renderSubmitButton?: DepositSubmitButtonRenderer; +}) { const { config, displayedAmount, @@ -179,7 +190,12 @@ const DepositScreenContent = memo(function DepositScreenContent() { paddingTop="16px" width="full" > - + diff --git a/src/systems/funding/components/deposit/DepositFooter.tsx b/src/systems/funding/components/deposit/DepositFooter.tsx index 0dfe2fc6f67..f9dcbccd369 100644 --- a/src/systems/funding/components/deposit/DepositFooter.tsx +++ b/src/systems/funding/components/deposit/DepositFooter.tsx @@ -2,11 +2,12 @@ import { memo } from 'react'; import { type SharedValue, useDerivedValue } from 'react-native-reanimated'; import { Box, Separator, useColorMode } from '@/design-system'; import { PerpsSwapButton } from '@/features/perps/components/PerpsSwapButton'; +import { useSharedValueState } from '@/hooks/reanimated/useSharedValueState'; import { useStableValue } from '@/hooks/useStableValue'; import { createDerivedStore } from '@/state/internal/createDerivedStore'; import { useStoreSharedValue } from '@/state/internal/hooks/useStoreSharedValue'; import { type InferStoreState } from '@/state/internal/types'; -import { DepositQuoteStatus, type DepositQuoteStoreType, getAccentColor } from '@/systems/funding/types'; +import { DepositQuoteStatus, type DepositQuoteStoreType, type DepositSubmitButtonRenderer, getAccentColor } from '@/systems/funding/types'; import { time } from '@/utils/time'; import { useDepositContext } from '../../contexts/DepositContext'; import { GasButton } from './gas/GasButton'; @@ -32,16 +33,27 @@ type DepositFooterProps = { inputAmountError: SharedValue; isSubmitting: SharedValue; onSubmit: () => Promise; + renderSubmitButton?: DepositSubmitButtonRenderer; }; -export const DepositFooter = memo(function DepositFooter({ inputAmountError, isSubmitting, onSubmit }: DepositFooterProps) { +export const DepositFooter = memo(function DepositFooter({ + inputAmountError, + isSubmitting, + onSubmit, + renderSubmitButton, +}: DepositFooterProps) { return ( <> - + ); }); @@ -79,9 +91,10 @@ type SubmitButtonProps = { inputAmountError: SharedValue; isSubmitting: SharedValue; onSubmit: () => Promise; + renderSubmitButton?: DepositSubmitButtonRenderer; }; -const SubmitButton = memo(function SubmitButton({ inputAmountError, isSubmitting, onSubmit }: SubmitButtonProps) { +const SubmitButton = memo(function SubmitButton({ inputAmountError, isSubmitting, onSubmit, renderSubmitButton }: SubmitButtonProps) { const { isDarkMode } = useColorMode(); const { config, theme, useQuoteStore } = useDepositContext(); const useCustomExecute = Boolean(config.execute); @@ -114,6 +127,23 @@ const SubmitButton = memo(function SubmitButton({ inputAmountError, isSubmitting return status === null || status === DepositQuoteStatus.Error || status === DepositQuoteStatus.InsufficientGas; }); + const submitButtonLabel = useSharedValueState(label, { pauseSync: !renderSubmitButton }); + const isSubmitButtonDisabled = useSharedValueState(disabled, { pauseSync: !renderSubmitButton }); + const isSubmitButtonProcessing = useSharedValueState(isSubmitting, { pauseSync: !renderSubmitButton }); + + if (renderSubmitButton) { + return ( + + {renderSubmitButton({ + disabled: isSubmitButtonDisabled, + isSubmitting: isSubmitButtonProcessing, + label: submitButtonLabel, + onSubmit, + })} + + ); + } + return ( diff --git a/src/systems/funding/types.ts b/src/systems/funding/types.ts index 15d1e0e0c7f..d6500aaed40 100644 --- a/src/systems/funding/types.ts +++ b/src/systems/funding/types.ts @@ -1,4 +1,5 @@ import { type Signer } from '@ethersproject/abstract-signer'; +import { type ReactNode } from 'react'; import { type Address } from 'viem'; import { type DerivedValue, type SharedValue } from 'react-native-reanimated'; import { type CrosschainQuote, type Quote, type Source } from '@rainbow-me/swaps'; @@ -201,6 +202,15 @@ export type DepositLabels = { title: string; }; +export type DepositSubmitButtonRenderParams = { + disabled: boolean; + isSubmitting: boolean; + label: string; + onSubmit: () => Promise; +}; + +export type DepositSubmitButtonRenderer = (params: DepositSubmitButtonRenderParams) => ReactNode; + /** * ### `DepositConfig` *