Files
com.blitzwallet/app/functions/CustomElements/halfModal.js
T
cb506c8c11 Multi static deposit addresses (#1012)
* Add accumulation address cap helper + pair key (Task 1)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Add forceNew + cap enforcement + addressesForOption to accumulation hook (Task 2)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Guard createAddress against re-entrant double-mint (Task 2 review fix)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Add i18n keys for multi accumulation addresses (Task 3)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Add accumulation address + option selector half-modals (Task 4)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Reuse getPairKey in option selector modal (Task 4 review fix)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Group accumulation home by option with per-option count (Task 5)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Manage multiple addresses + option switching in accumulation detail (Task 6)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Guard accumulation detail against externally-emptied option (Task 6 review fix)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Add create-new-address button + direct-address display to deposit QR view (Task 7)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Add address-selector list icon to deposit QR header (Task 8)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Cap-gate create wizard + always mint additional address (Task 9)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* remove manual create button in favor of automatic

* fix select address page

* fix opacity

* improve details page

* fixing translations

* adding dislcimer to address details page

* adding reindex scan

* fixing background color

* fixing camel case var name

* minor correctness fixes

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 13:36:39 -04:00

1008 lines
36 KiB
JavaScript

import React, { useCallback, useEffect, useRef, useState } from 'react';
import { StyleSheet, View, TouchableOpacity } from 'react-native';
import {
KeyboardAvoidingView,
KeyboardController,
} from 'react-native-keyboard-controller';
import { useFocusEffect, useNavigation } from '@react-navigation/native';
import { COLORS, CONTENT_KEYBOARD_OFFSET, SIZES } from '../../constants';
import {
HalfModalSendOptions,
HalfModalReceiveOptions,
} from '../../components/admin';
import {
ConfirmSMSPayment,
ConfirmVPNPage,
SwitchGenerativeAIModel,
} from '../../components/admin/homeComponents/apps';
import ThemeText from './textTheme';
import ThemeIcon from './themeIcon';
import ConfirmGiftCardPurchase from '../../components/admin/homeComponents/apps/giftCards/confimPurchase';
import ConfirmExportPayments from '../../components/admin/homeComponents/exportTransactions/exportTracker';
import ConfirmChatGPTPage from '../../components/admin/homeComponents/apps/chatGPT/components/confirmationPage';
import AddContactsHalfModal from '../../components/admin/homeComponents/contacts/addContactsHalfModal';
import GetThemeColors from '../../hooks/themeColors';
// import MyProfileQRCode from '../../components/admin/homeComponents/contacts/internalComponents/profilePageQrPopup';
import ExpandedMessageHalfModal from '../../components/admin/homeComponents/contacts/expandedMessageHalfModal';
// import LiquidAddressModal from '../../components/admin/homeComponents/settingsContent/bankComponents/invoicePopup';
import useHandleBackPressNew from '../../hooks/useHandleBackPressNew';
import { KEYBOARDTIMEOUT } from '../../constants/styles';
import { useGlobalThemeContext } from '../../../context-store/theme';
import AddPOSItemHalfModal from '../../components/admin/homeComponents/settingsContent/posPath/items/addItemHalfModal';
import { useGlobalInsets } from '../../../context-store/insetsProvider';
import EditLNURLContactOnReceivePage from '../../components/admin/homeComponents/receiveBitcoin/editLNURLContact';
import CustomInputHalfModal from './CustomInputHalfModal';
import CustomQrCode from '../../components/admin/homeComponents/settingsContent/bankComponents/invoicePopup';
import ChooseLNURLCopyFormat from '../../components/admin/homeComponents/receiveBitcoin/lnurlCopyType';
import LRC20AssetSelectorHalfModal from '../lrc20/lrc20HalfModal';
import LRC20TokenInformation from '../lrc20/lrc20TokenDataHalfModal';
import SelectAltAccountHalfModal from '../../components/admin/homeComponents/settingsContent/accountComponents/SelectAltAccountHalfModal';
import ConfirmSMSReceiveCode from '../../components/admin/homeComponents/apps/sms4sats/receiveCodeConfirmation';
import EditGiftHalfModal from '../../components/admin/homeComponents/contacts/internalComponents/editGiftHalfModal';
import ViewGiftCardCodePage from '../../components/admin/homeComponents/contacts/viewGiftCardCode';
import ViewAllGiftCards from '../../components/admin/homeComponents/contacts/viewAllGiftCards';
import ViewAllTokensHalfModal from '../../components/admin/homeComponents/homeLightning/viewAllTokensHalfModal';
import CreateAccumulationAddressModal from '../../components/admin/homeComponents/accumulationAddresses/CreateAccumulationAddressModal';
import AccumulationAddressSelectHalfModal from '../../components/admin/homeComponents/accumulationAddresses/AccumulationAddressSelectHalfModal';
import Animated, {
useSharedValue,
useAnimatedStyle,
withTiming,
withSpring,
cancelAnimation,
} from 'react-native-reanimated';
import { scheduleOnRN } from 'react-native-worklets';
import { GestureDetector, Gesture } from 'react-native-gesture-handler';
import { useAppStatus } from '../../../context-store/appStatus';
import SelectLRC20Token from '../../components/admin/homeComponents/sendBitcoin/components/selectLRC20Token';
import SelectPaymentMethod from '../../components/admin/homeComponents/sendBitcoin/components/selectPaymentMethod';
import SelectReceiveAsset from '../../components/admin/homeComponents/receiveBitcoin/selectReceiveAsset';
import AddReceiveMessageHalfModal from '../../components/admin/homeComponents/receiveBitcoin/addMessageHalfModal';
import ClaimGiftScreen from '../../components/admin/homeComponents/gifts/claimGiftScreen';
import CreatePoolFlow from '../../components/admin/homeComponents/pools/createPoolFlow';
import {
SelectContactRequestCurrency,
SelectPaymentType,
} from '../../components/admin/homeComponents/contacts';
import ClosePoolConfirmation from '../../components/admin/homeComponents/pools/closePoolConfirmation';
import ContributeToPoolHalfModal from '../../components/admin/homeComponents/pools/contributeToPoolHalfModal';
import AddMoneyToSavingsHalfModal from '../../components/admin/homeComponents/savings/AddMoneyToSavingsHalfModal';
import WithdrawFromSavingsHalfModal from '../../components/admin/homeComponents/savings/WithdrawFromSavingsHalfModal';
import { SavingsProvider } from '../../../context-store/savingsContext';
import HowSavingsWorks from '../../components/admin/homeComponents/savings/howItWorks';
import ClaimGiftHomeHalfModal from '../../components/admin/homeComponents/gifts/claimGiftHomeHalfModal';
import AddGiftQuantityHalfModal from '../../components/admin/homeComponents/gifts/addGiftQuantityHalfModal';
import SwapFlowHalfModal from '../../components/admin/homeComponents/swaps/swapFlowHalfModal';
import TxFilterHalfModal from '../../components/admin/homeComponents/homeLightning/txFilterHalfModal';
import OnlineListingsFilterHalfModal from '../../components/admin/homeComponents/apps/onlineListings/onlineListingsFilterHalfModal';
import PayLinkCurrencySelect from '../../components/admin/homeComponents/payLinks/components/payLinkCurrencySelect';
import DisplayCurrencySelect from '../../components/admin/homeComponents/currencyPicker/displayCurrencySelect';
import LnurlReceiveCurrencySelect from '../../components/admin/homeComponents/receiveBitcoin/lnurlReceiveCurrencySelect';
import StablecoinAssetPickerHalfModal from './stablecoinAssetPickerHalfModal';
import RemoveBudgetHalfModal from '../../components/admin/homeComponents/analytics/removeBudgetHalfModal';
import BudgetWarningModal from '../../components/admin/homeComponents/sendBitcoin/components/nearBudgetLimitWarning';
import BTCMapMerchantContent from '../../screens/inAccount/btcMapMerchant';
import BTCMapFilterContent from '../../screens/inAccount/btcMapFilter';
import BTCMapListContent from '../../screens/inAccount/btcMapList';
import HalfModalDepositFunds from '../../components/admin/homeComponents/homeLightning/halfModalDepositFunds';
import ShareInvoicePayLinkModal from '../../components/admin/homeComponents/receiveBitcoin/shareInvoicePayLinkModal';
import RootstockSwapInfo from '../../components/admin/homeComponents/settingsContent/swapsComponents/rootstockSwapInfo';
import SelectSwapNetworkHalfModal from '../../components/admin/homeComponents/settingsContent/swapsComponents/selectSwapNetworkHalfModal';
import ExportLeavesProgress from '../../components/admin/homeComponents/settingsContent/leaves/exportLeavesProgress';
const CONTENT_TYPES_WITH_MOUNT_FOCUS = new Set([
'AddMessageReceivePage',
'addContacts',
]);
// Flip to 'arrow' for the plain app-standard back arrow, or 'circle' for the
// circular chevron that matches the reference screenshot.
function HalfModalBackButton({
onPress,
backgroundOffset,
backgroundColor,
theme,
darkModeType,
btnType = 'circle',
}) {
return (
<TouchableOpacity onPress={onPress} style={styles.backButton} hitSlop={10}>
<View
style={[
styles.backButtonCircle,
{
backgroundColor:
theme && darkModeType ? backgroundColor : backgroundOffset,
},
]}
>
<ThemeIcon
iconName={btnType === 'circle' ? 'ChevronLeft' : 'X'}
size={22}
/>
</View>
</TouchableOpacity>
);
}
export default function CustomHalfModal(props) {
const { theme, darkModeType } = useGlobalThemeContext();
const { screenDimensions } = useAppStatus();
const navigation = useNavigation();
const contentType = props?.route?.params?.wantedContent;
const slideHeight = props?.route?.params?.sliderHight || 0.5;
const { backgroundColor, backgroundOffset, transparentOveraly } =
GetThemeColors();
const [contentHeight, setContentHeight] = useState(0);
// { onPress, title } when the active content registers a back step, else null
const [backNav, setBackNav] = useState(null);
const [isKeyboardActive, setIsKeyboardActive] = useState(
contentType === 'AddMessageReceivePage' ? true : false,
);
const isScreenActive = useRef(false);
const { bottomPadding, topPadding } = useGlobalInsets();
const didHandleBackpress = useRef(false);
const closeTimerRef = useRef(null);
const shouldDismissKeyboardOnMount =
!CONTENT_TYPES_WITH_MOUNT_FOCUS.has(contentType);
const translateY = useSharedValue(screenDimensions.height);
const animatedHeight = useSharedValue(screenDimensions.height * slideHeight);
const slideIn = useCallback(() => {
translateY.value = withTiming(0, { duration: 200 });
}, [translateY]);
const slideOut = useCallback(() => {
translateY.value = withTiming(screenDimensions.height, { duration: 200 });
}, [screenDimensions.height, translateY]);
useEffect(() => {
if (contentHeight) {
animatedHeight.value = withTiming(contentHeight, { duration: 200 });
}
}, [contentHeight]);
useFocusEffect(
useCallback(() => {
isScreenActive.current = true;
return () => {
isScreenActive.current = false;
};
}, [contentType]),
);
const handleBackPressFunction = useCallback(
customBackFunction => {
const resolvedCustomBackFunction =
typeof customBackFunction === 'function' ? customBackFunction : null;
if (!isScreenActive.current) return;
if (didHandleBackpress.current) return true;
didHandleBackpress.current = true;
const keyboardVisible = KeyboardController.isVisible();
KeyboardController.dismiss();
slideOut();
if (closeTimerRef.current) {
clearTimeout(closeTimerRef.current);
}
closeTimerRef.current = setTimeout(
() => {
closeTimerRef.current = null;
if (resolvedCustomBackFunction) {
resolvedCustomBackFunction();
} else {
navigation.goBack();
}
},
keyboardVisible ? KEYBOARDTIMEOUT : 200,
);
return true;
},
[navigation, slideOut],
);
useHandleBackPressNew(handleBackPressFunction);
useEffect(() => {
if (shouldDismissKeyboardOnMount && KeyboardController.isVisible()) {
KeyboardController.dismiss();
}
slideIn();
return () => {
if (closeTimerRef.current) {
clearTimeout(closeTimerRef.current);
closeTimerRef.current = null;
}
cancelAnimation(translateY);
cancelAnimation(animatedHeight);
};
}, [shouldDismissKeyboardOnMount, slideIn]);
const renderContent = () => {
switch (contentType) {
case 'sendOptions':
return (
<HalfModalSendOptions
handleBackPressFunction={handleBackPressFunction}
setIsKeyboardActive={setIsKeyboardActive}
isKeyboardActive={isKeyboardActive}
theme={theme}
darkModeType={darkModeType}
slideHeight={slideHeight}
isScreenActive={isScreenActive}
setBackNav={setBackNav}
setContentHeight={setContentHeight}
selectedPaymentMethod={props.route.params?.selectedPaymentMethod}
/>
);
case 'receiveOptions':
return (
<HalfModalReceiveOptions
setIsKeyboardActive={setIsKeyboardActive}
theme={theme}
darkModeType={darkModeType}
slideHeight={slideHeight}
scrollPosition={props.route.params?.scrollPosition}
handleBackPressFunction={handleBackPressFunction}
setContentHeight={setContentHeight}
isScreenActive={isScreenActive}
setBackNav={setBackNav}
selectedRequestMethod={props.route.params?.selectedRequestMethod}
/>
);
case 'confirmSMS':
return (
<ConfirmSMSPayment
theme={theme}
darkModeType={darkModeType}
message={props.route.params?.message}
phoneNumber={props.route.params?.phoneNumber}
areaCodeNum={props.route.params?.areaCodeNum}
normalizedPhoneNumber={props.route.params?.normalizedPhoneNumber}
sendTextMessage={props.route.params?.sendTextMessage}
page={'sendSMS'}
/>
);
case 'confirmSMSReceive':
return (
<ConfirmSMSReceiveCode
theme={theme}
darkModeType={darkModeType}
serviceCode={props.route.params?.serviceCode}
location={props.route.params?.location}
title={props.route.params?.title}
imgSrc={props.route.params?.imgSrc}
getReceiveCode={props.route.params?.getReceiveCode}
/>
);
case 'confirmVPN':
return (
<ConfirmVPNPage
theme={theme}
darkModeType={darkModeType}
price={props.route.params?.price}
duration={props.route.params?.duration}
country={props.route.params?.country}
createVPN={props.route.params?.createVPN}
slideHeight={slideHeight}
/>
);
case 'giftCardConfirm':
return (
<ConfirmGiftCardPurchase
theme={theme}
darkModeType={darkModeType}
quantity={props.route.params?.quantity}
price={props.route.params?.price}
productId={props.route.params?.productId}
purchaseGiftCard={props.route.params?.purchaseGiftCard}
email={props.route.params?.email}
blitzUsername={props.route.params?.blitzUsername}
/>
);
case 'exportTransactions':
return (
<ConfirmExportPayments
theme={theme}
darkModeType={darkModeType}
startExport={props.route.params?.startExport}
/>
);
case 'switchGenerativeAiModel':
return (
<SwitchGenerativeAIModel
theme={theme}
darkModeType={darkModeType}
setSelectedRecieveOption={props.route.params?.setSelectedModel}
setIsKeyboardActive={setIsKeyboardActive}
/>
);
case 'chatGPT':
return (
<ConfirmChatGPTPage
setContentHeight={setContentHeight}
setBackNav={setBackNav}
/>
);
case 'addContacts':
return (
<AddContactsHalfModal
theme={theme}
darkModeType={darkModeType}
slideHeight={slideHeight}
setIsKeyboardActive={setIsKeyboardActive}
startingSearchValue={props.route.params?.startingSearchValue}
handleBackPressFunction={handleBackPressFunction}
isScreenActive={isScreenActive}
/>
);
// case 'myProfileQRcode':
// return <MyProfileQRCode theme={theme} />;
case 'expandedContactMessage':
return (
<ExpandedMessageHalfModal
message={props.route.params?.message}
slideHeight={slideHeight}
/>
);
case 'customQrCode':
return (
<CustomQrCode
data={props.route.params?.data}
setContentHeight={setContentHeight}
/>
);
case 'addPOSItemsHalfModal':
return (
<AddPOSItemHalfModal
isKeyboardActive={isKeyboardActive}
setIsKeyboardActive={setIsKeyboardActive}
initialSettings={props.route.params?.initialSettings}
handleBackPressFunction={handleBackPressFunction}
/>
);
// case 'editLNURLOnReceive':
// return (
// <EditLNURLContactOnReceivePage
// theme={theme}
// darkModeType={darkModeType}
// slideHeight={slideHeight}
// isKeyboardActive={isKeyboardActive}
// setIsKeyboardActive={setIsKeyboardActive}
// setContentHeight={setContentHeight}
// handleBackPressFunction={handleBackPressFunction}
// />
// );
case 'customInputText':
return (
<CustomInputHalfModal
handleBackPressFunction={handleBackPressFunction}
theme={theme}
darkModeType={darkModeType}
slideHeight={slideHeight}
setContentHeight={setContentHeight}
message={props?.route?.params?.message}
type={props?.route?.params?.type}
returnLocation={props?.route?.params?.returnLocation}
passedParams={props?.route?.params?.passedParams}
forceUSD={props?.route?.params?.forceUSD}
setBackNav={setBackNav}
/>
);
// case 'chooseLNURLCopyFormat':
// return <ChooseLNURLCopyFormat />;
case 'LRC20AssetSelectorHalfModal':
return (
<LRC20AssetSelectorHalfModal
theme={theme}
darkModeType={darkModeType}
/>
);
case 'LRC20TokenInformation':
return (
<LRC20TokenInformation
theme={theme}
darkModeType={darkModeType}
tokenIdentifier={props?.route?.params?.tokenIdentifier}
slideHeight={slideHeight}
setContentHeight={setContentHeight}
/>
);
case 'SelectAltAccount':
return (
<SelectAltAccountHalfModal
slideHeight={slideHeight}
selectedFrom={props?.route?.params?.selectedFrom}
selectedTo={props?.route?.params?.selectedTo}
transferType={props?.route?.params?.transferType}
/>
);
case 'giftCardSendAndReceiveOption':
return (
<EditGiftHalfModal
theme={theme}
darkModeType={darkModeType}
slideHeight={slideHeight}
setContentHeight={setContentHeight}
uuid={props?.route?.params?.uuid}
selectedContact={props?.route?.params?.selectedContact}
imageData={props?.route?.params?.imageData}
/>
);
case 'SelectPaymentType':
return (
<SelectPaymentType
theme={theme}
handleBackPressFunction={handleBackPressFunction}
darkModeType={darkModeType}
slideHeight={slideHeight}
setContentHeight={setContentHeight}
selectedContact={props?.route?.params?.selectedContact}
imageData={props?.route?.params?.imageData}
paymentType={props?.route?.params?.paymentType}
/>
);
case 'SelectContactRequestCurrency':
return (
<SelectContactRequestCurrency
theme={theme}
handleBackPressFunction={handleBackPressFunction}
darkModeType={darkModeType}
slideHeight={slideHeight}
setContentHeight={setContentHeight}
selectedRecieveOption={props?.route?.params?.selectedRecieveOption}
fromPage={props?.route?.params?.fromPage}
onSelectMethod={props?.route?.params?.onSelectMethod}
/>
);
case 'viewContactsGiftInfo':
return (
<ViewGiftCardCodePage
theme={theme}
darkModeType={darkModeType}
slideHeight={slideHeight}
giftCardInfo={props?.route?.params?.giftCardInfo}
from={props?.route?.params?.from}
isOutgoingPayment={props?.route?.params?.isOutgoingPayment}
message={props?.route?.params?.message}
/>
);
case 'ViewAllGiftCards':
return (
<ViewAllGiftCards
theme={theme}
darkModeType={darkModeType}
slideHeight={slideHeight}
/>
);
case 'SelectLRC20Token':
return (
<SelectLRC20Token
handleBackPressFunction={handleBackPressFunction}
isKeyboardActive={isKeyboardActive}
setIsKeyboardActive={setIsKeyboardActive}
theme={theme}
darkModeType={darkModeType}
/>
);
case 'SelectPaymentMethod':
return (
<SelectPaymentMethod
selectedPaymentMethod={props?.route?.params?.selectedPaymentMethod}
handleBackPressFunction={handleBackPressFunction}
fromPage={props?.route?.params?.fromPage}
onSelectMethod={props?.route?.params?.onSelectMethod}
isKeyboardActive={isKeyboardActive}
setIsKeyboardActive={setIsKeyboardActive}
theme={theme}
darkModeType={darkModeType}
/>
);
case 'ClaimGiftScreen':
return (
<ClaimGiftScreen
url={props?.route?.params?.url}
claimType={props?.route?.params?.claimType}
expertMode={props?.route?.params?.expertMode}
customGiftIndex={props?.route?.params?.customGiftIndex}
theme={theme}
darkModeType={darkModeType}
/>
);
case 'SelectReceiveAsset':
return (
<SelectReceiveAsset
endReceiveType={props?.route?.params?.endReceiveType}
selectedRecieveOption={props?.route?.params?.selectedRecieveOption}
handleBackPressFunction={handleBackPressFunction}
theme={theme}
darkModeType={darkModeType}
/>
);
case 'AddMessageReceivePage':
return (
<AddReceiveMessageHalfModal
memo={props?.route?.params?.memo}
handleBackPressFunction={handleBackPressFunction}
setContentHeight={setContentHeight}
theme={theme}
darkModeType={darkModeType}
/>
);
case 'createPoolFlow':
return (
<CreatePoolFlow
route={props?.route}
setContentHeight={setContentHeight}
handleBackPressFunction={handleBackPressFunction}
navigate={navigation}
setBackNav={setBackNav}
/>
);
case 'closePoolConfirmation':
return (
<ClosePoolConfirmation
pool={props?.route?.params?.pool}
autoStart={props?.route?.params?.autoStart}
setContentHeight={setContentHeight}
handleBackPressFunction={handleBackPressFunction}
/>
);
case 'contributeToPool':
return (
<ContributeToPoolHalfModal
pool={props?.route?.params?.pool}
poolId={props?.route?.params?.poolId}
setContentHeight={setContentHeight}
handleBackPressFunction={handleBackPressFunction}
setBackNav={setBackNav}
/>
);
case 'addGiftQuantity':
return (
<AddGiftQuantityHalfModal
amount={props?.route?.params?.amount}
amountValue={props?.route?.params?.amountValue}
dollarAmount={props?.route?.params?.dollarAmount}
giftDenomination={props?.route?.params?.giftDenomination}
setContentHeight={setContentHeight}
handleBackPressFunction={handleBackPressFunction}
setBackNav={setBackNav}
/>
);
case 'addMoneyToSavings':
return (
<SavingsProvider>
<AddMoneyToSavingsHalfModal
selectedGoalUUID={props?.route?.params?.selectedGoalUUID}
setContentHeight={setContentHeight}
handleBackPressFunction={handleBackPressFunction}
setBackNav={setBackNav}
/>
</SavingsProvider>
);
case 'withdrawFromSavings':
return (
<SavingsProvider>
<WithdrawFromSavingsHalfModal
currentBalance={props?.route?.params?.currentBalance}
selectedGoalUUID={props?.route?.params?.selectedGoalUUID}
setContentHeight={setContentHeight}
handleBackPressFunction={handleBackPressFunction}
setBackNav={setBackNav}
/>
</SavingsProvider>
);
case 'howSavingsWorks':
return (
<HowSavingsWorks
currentBalance={props?.route?.params?.currentBalance}
setContentHeight={setContentHeight}
handleBackPressFunction={handleBackPressFunction}
/>
);
case 'ViewAllTokensHalfModal':
return (
<ViewAllTokensHalfModal
handleBackPressFunction={handleBackPressFunction}
setContentHeight={setContentHeight}
setBackNav={setBackNav}
/>
);
case 'ClaimGiftHomeHalfModal':
return (
<ClaimGiftHomeHalfModal
handleBackPressFunction={handleBackPressFunction}
setContentHeight={setContentHeight}
setIsKeyboardActive={setIsKeyboardActive}
/>
);
case 'swapFlow':
return (
<SwapFlowHalfModal
setContentHeight={setContentHeight}
handleBackPressFunction={handleBackPressFunction}
setBackNav={setBackNav}
/>
);
case 'txFilter':
return (
<TxFilterHalfModal
currentFilter={props?.route?.params?.currentFilter}
onSelectFilter={props?.route?.params?.onSelectFilter}
handleBackPressFunction={handleBackPressFunction}
setContentHeight={setContentHeight}
/>
);
case 'onlineListingsFilter':
return (
<OnlineListingsFilterHalfModal
currentFilter={props?.route?.params?.currentFilter}
onSelectFilter={props?.route?.params?.onSelectFilter}
categoryOptions={props?.route?.params?.categoryOptions}
handleBackPressFunction={handleBackPressFunction}
setContentHeight={setContentHeight}
setIsKeyboardActive={setIsKeyboardActive}
setBackNav={setBackNav}
/>
);
case 'payLinkCurrencySelect':
return (
<PayLinkCurrencySelect
currentCurrency={props?.route?.params?.currentCurrency}
onSelectCurrency={props?.route?.params?.onSelectCurrency}
handleBackPressFunction={handleBackPressFunction}
setContentHeight={setContentHeight}
/>
);
case 'displayCurrencySelect':
return (
<DisplayCurrencySelect
currentCurrency={props?.route?.params?.currentCurrency}
onSelectCurrency={props?.route?.params?.onSelectCurrency}
handleBackPressFunction={handleBackPressFunction}
setContentHeight={setContentHeight}
/>
);
case 'lnurlReceiveCurrencySelect':
return (
<LnurlReceiveCurrencySelect
handleBackPressFunction={handleBackPressFunction}
setContentHeight={setContentHeight}
/>
);
case 'stablecoinAssetPicker':
return (
<StablecoinAssetPickerHalfModal
selectedChain={props?.route?.params?.selectedChain}
address={props?.route?.params?.address}
handleBackPressFunction={handleBackPressFunction}
setContentHeight={setContentHeight}
/>
);
case 'createAccumulationAddress':
return (
<CreateAccumulationAddressModal
handleBackPressFunction={handleBackPressFunction}
setContentHeight={setContentHeight}
setBackNav={setBackNav}
/>
);
case 'accumulationAddressSelect':
return (
<AccumulationAddressSelectHalfModal
addresses={props?.route?.params?.addresses}
selectedId={props?.route?.params?.selectedId}
onSelect={props?.route?.params?.onSelect}
handleBackPressFunction={handleBackPressFunction}
setContentHeight={setContentHeight}
/>
);
case 'RemoveBudgetHalfModal':
return (
<RemoveBudgetHalfModal
handleBackPressFunction={handleBackPressFunction}
setContentHeight={setContentHeight}
/>
);
case 'nearBudgetLimitWarning':
return (
<BudgetWarningModal
handleBackPressFunction={handleBackPressFunction}
sendingAmount={props?.route?.params?.sendingAmount}
/>
);
case 'btcMapMerchant':
return (
<BTCMapMerchantContent
handleBackPressFunction={handleBackPressFunction}
placeId={props?.route?.params?.placeId}
source={props?.route?.params?.source}
setContentHeight={setContentHeight}
/>
);
case 'btcMapFilter':
return (
<BTCMapFilterContent
currentFilter={props?.route?.params?.currentFilter}
onSelectFilter={props?.route?.params?.onSelectFilter}
handleBackPressFunction={handleBackPressFunction}
setContentHeight={setContentHeight}
/>
);
case 'btcMapList':
return (
<BTCMapListContent
bbox={props?.route?.params?.bbox}
categories={props?.route?.params?.categories}
distanceUnit={props?.route?.params?.distanceUnit}
userLocation={props?.route?.params?.userLocation}
handleBackPressFunction={handleBackPressFunction}
setContentHeight={setContentHeight}
placeCount={props?.route?.params?.placeCount}
/>
);
case 'depositFunds':
return (
<HalfModalDepositFunds
handleBackPressFunction={handleBackPressFunction}
setContentHeight={setContentHeight}
setBackNav={setBackNav}
theme={theme}
darkModeType={darkModeType}
showLightning={props.route.params?.showLightning ?? false}
/>
);
case 'receiveMethodOptions':
return (
<HalfModalDepositFunds
handleBackPressFunction={handleBackPressFunction}
setContentHeight={setContentHeight}
setBackNav={setBackNav}
theme={theme}
darkModeType={darkModeType}
showLightning={true}
/>
);
case 'shareInvoicePaylink':
return (
<ShareInvoicePayLinkModal
rawAmount={props.route.params?.rawAmount}
currencyType={props.route.params?.currencyType}
onCreated={props.route.params?.onCreated}
setContentHeight={setContentHeight}
sharePayLinkCache={props.route.params?.sharePayLinkCache}
/>
);
case 'rootstockSwapInfo':
return (
<RootstockSwapInfo
swap={props?.route?.params?.swap}
handleBackPressFunction={handleBackPressFunction}
/>
);
case 'selectSwapNetwork':
return (
<SelectSwapNetworkHalfModal
handleBackPressFunction={handleBackPressFunction}
/>
);
case 'exportLeavesProgress':
return (
<ExportLeavesProgress
onExported={props?.route?.params?.onExported}
handleBackPressFunction={handleBackPressFunction}
/>
);
default:
return <ThemeText content={'TST'} />;
}
};
const panGesture = Gesture.Pan()
.onUpdate(e => {
if (e.translationY > 0) {
translateY.value = e.translationY;
}
})
.onEnd(e => {
if (e.translationY > 100) {
scheduleOnRN(handleBackPressFunction);
} else {
translateY.value = withSpring(0);
}
});
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ translateY: translateY.value }],
height: animatedHeight.value,
}));
return (
<KeyboardAvoidingView
behavior={'padding'}
style={styles.keyboardAvoidingView}
>
<TouchableOpacity
style={[styles.backdrop, { backgroundColor: transparentOveraly }]}
activeOpacity={1}
onPress={handleBackPressFunction}
/>
<Animated.View
style={[
styles.contentContainer,
animatedStyle,
{
backgroundColor: 'black',
marginTop: topPadding,
},
]}
>
<View
style={{
flex: 1,
backgroundColor:
theme && darkModeType ? backgroundOffset : backgroundColor,
paddingBottom:
contentType === 'switchGenerativeAiModel' ||
contentType === 'addPOSItemsHalfModal' ||
// contentType === 'editLNURLOnReceive' ||
contentType === 'addContacts' ||
contentType === 'SelectLRC20Token' ||
contentType === 'sendOptions' ||
contentType === 'receiveOptions' ||
contentType === 'createPoolFlow' ||
contentType === 'ClaimGiftHomeHalfModal' ||
contentType === 'btcMapList'
? isKeyboardActive
? CONTENT_KEYBOARD_OFFSET
: contentType === 'switchGenerativeAiModel' ||
contentType === 'addContacts' ||
contentType === 'sendOptions' ||
contentType === 'createPoolFlow' ||
contentType === 'SelectLRC20Token' ||
contentType === 'btcMapList'
? 0
: contentType === 'receiveOptions'
? 0
: bottomPadding
: contentType === 'onlineListingsFilter' ||
contentType === 'depositFunds' ||
contentType === 'receiveMethodOptions' ||
contentType === 'createAccumulationAddress'
? 0
: bottomPadding,
}}
>
<GestureDetector gesture={panGesture}>
<View style={styles.topBarContainer}>
{backNav ? (
<View style={styles.headerRow}>
{typeof backNav.onPress === 'function' && (
<HalfModalBackButton
onPress={backNav.onPress}
backgroundOffset={backgroundOffset}
btnType={backNav.btnType}
theme={theme}
darkModeType={darkModeType}
backgroundColor={backgroundColor}
/>
)}
{!!backNav.title && (
<ThemeText
CustomNumberOfLines={1}
styles={styles.headerTitle}
content={backNav.title}
/>
)}
{!!backNav.rightElement && (
<View style={styles.headerRight}>
{backNav.rightElement}
</View>
)}
</View>
) : (
<View
style={[
styles.topBar,
{
backgroundColor:
theme && darkModeType
? backgroundColor
: backgroundOffset,
},
]}
/>
)}
</View>
</GestureDetector>
{renderContent()}
</View>
</Animated.View>
</KeyboardAvoidingView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
keyboardAvoidingView: {
flex: 1,
justifyContent: 'flex-end',
},
backdrop: {
...StyleSheet.absoluteFillObject,
},
topBarContainer: {
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
paddingTop: 10,
alignItems: 'center',
justifyContent: 'center',
},
topBar: {
width: 120,
height: 8,
marginTop: 10,
borderRadius: 8,
marginBottom: 20,
},
headerRow: {
width: '100%',
minHeight: 36,
marginTop: 10,
marginBottom: 20,
alignItems: 'center',
justifyContent: 'center',
},
headerTitle: {
fontSize: SIZES.large,
includeFontPadding: false,
textAlign: 'center',
paddingHorizontal: 56,
},
backButton: {
position: 'absolute',
left: 20,
top: 0,
bottom: 0,
justifyContent: 'center',
zIndex: 3,
},
backButtonCircle: {
width: 36,
height: 36,
borderRadius: 18,
alignItems: 'center',
justifyContent: 'center',
},
headerRight: {
position: 'absolute',
right: 20,
top: 0,
bottom: 0,
justifyContent: 'center',
zIndex: 3,
},
contentContainer: {
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
flexShrink: 1,
overflow: 'hidden',
},
});