REF: Use footer

This commit is contained in:
Marcos Rodriguez Velez 2024-07-01 12:58:19 -04:00
parent 4135a1618c
commit eb139c5320
No known key found for this signature in database
GPG key ID: 6030B2F48CCE86D7
4 changed files with 74 additions and 70 deletions

View file

@ -1,5 +1,6 @@
import React, { forwardRef, useImperativeHandle, useRef } from 'react';
import React, { forwardRef, useImperativeHandle, useRef, ReactElement, ComponentType } from 'react';
import { SheetSize, TrueSheet, TrueSheetProps } from '@lodev09/react-native-true-sheet';
import { StyleSheet, View } from 'react-native';
interface BottomModalProps extends TrueSheetProps {
children?: React.ReactNode;
@ -7,6 +8,8 @@ interface BottomModalProps extends TrueSheetProps {
name?: string;
isGrabberVisible?: boolean;
sizes?: SheetSize[] | undefined;
footer?: ReactElement | ComponentType<any>;
footerDefaultMargins?: boolean | number;
}
export interface BottomModalHandle {
@ -15,7 +18,10 @@ export interface BottomModalHandle {
}
const BottomModal = forwardRef<BottomModalHandle, BottomModalProps>(
({ name, onClose, onPresent, onSizeChange, isGrabberVisible = true, sizes = ['auto'], children, ...props }, ref) => {
(
{ name, onClose, onPresent, onSizeChange, isGrabberVisible = true, sizes = ['auto'], footer, footerDefaultMargins, children, ...props },
ref,
) => {
const trueSheetRef = useRef<TrueSheet>(null);
useImperativeHandle(ref, () => ({
@ -35,6 +41,19 @@ const BottomModal = forwardRef<BottomModalHandle, BottomModalProps>(
},
}));
const stlyes = StyleSheet.create({
footerContainer: { padding: typeof footerDefaultMargins === 'number' ? footerDefaultMargins : 40, alignItems: 'center' },
});
let FooterComponent: ReactElement | ComponentType<any> | undefined;
if (footer) {
if (React.isValidElement(footer)) {
FooterComponent = footerDefaultMargins ? <View style={stlyes.footerContainer}>{footer}</View> : footer;
} else {
FooterComponent = footer;
}
}
return (
<TrueSheet
name={name ?? 'BottomModal'}
@ -46,7 +65,7 @@ const BottomModal = forwardRef<BottomModalHandle, BottomModalProps>(
onPresent={onPresent}
onSizeChange={onSizeChange}
grabber={isGrabberVisible}
FooterComponent={FooterComponent}
{...props}
>
{children}

View file

@ -7,7 +7,7 @@ import * as BlueElectrum from '../../blue_modules/BlueElectrum';
import { fiatToBTC, satoshiToBTC } from '../../blue_modules/currency';
import triggerHapticFeedback, { HapticFeedbackTypes } from '../../blue_modules/hapticFeedback';
import Notifications from '../../blue_modules/notifications';
import { BlueButtonLink, BlueCard, BlueLoading, BlueSpacing20, BlueSpacing40, BlueText } from '../../BlueComponents';
import { BlueButtonLink, BlueCard, BlueLoading, BlueSpacing40, BlueText } from '../../BlueComponents';
import DeeplinkSchemaMatch from '../../class/deeplink-schema-match';
import AmountInput from '../../components/AmountInput';
import BottomModal from '../../components/BottomModal';
@ -346,6 +346,15 @@ const ReceiveDetails = () => {
onClose={dismissCustomAmountModal}
backgroundColor={colors.modal}
contentContainerStyle={styles.modalContent}
footerDefaultMarginsEnabled
footer={
<Button
testID="CustomAmountSaveButton"
style={[styles.modalButton, stylesHook.modalButton]}
title={loc.receive.details_create}
onPress={createCustomAmountAddress}
/>
}
>
<AmountInput unit={customUnit} amount={customAmount || ''} onChangeText={setCustomAmount} onAmountUnitChange={setCustomUnit} />
<View style={[styles.customAmount, stylesHook.customAmount]}>
@ -359,17 +368,6 @@ const ReceiveDetails = () => {
testID="CustomAmountDescription"
/>
</View>
<BlueSpacing20 />
<View>
<Button
testID="CustomAmountSaveButton"
style={[styles.modalButton, stylesHook.modalButton]}
title={loc.receive.details_create}
onPress={createCustomAmountAddress}
/>
<BlueSpacing20 />
</View>
<BlueSpacing20 />
</BottomModal>
);
};

View file

@ -1165,16 +1165,6 @@ const SendDetails = () => {
root: {
backgroundColor: colors.elevated,
},
modalContent: {
backgroundColor: colors.modal,
borderTopColor: colors.borderTopColor,
borderWidth: colors.borderWidth,
},
optionsContent: {
backgroundColor: colors.modal,
borderTopColor: colors.borderTopColor,
borderWidth: colors.borderWidth,
},
feeModalItemActive: {
backgroundColor: colors.feeActive,
},
@ -1256,40 +1246,15 @@ const SendDetails = () => {
];
return (
<BottomModal ref={feeModalRef}>
<View style={[styles.modalContent, stylesHook.modalContent]}>
{options.map(({ label, time, fee, rate, active, disabled }, index) => (
<TouchableOpacity
accessibilityRole="button"
key={label}
disabled={disabled}
onPress={() => {
setFeePrecalc(fp => ({ ...fp, current: fee }));
feeModalRef.current?.dismiss();
setCustomFee(rate.toString());
}}
style={[styles.feeModalItem, active && styles.feeModalItemActive, active && !disabled && stylesHook.feeModalItemActive]}
>
<View style={styles.feeModalRow}>
<Text style={[styles.feeModalLabel, disabled ? stylesHook.feeModalItemTextDisabled : stylesHook.feeModalLabel]}>
{label}
</Text>
<View style={[styles.feeModalTime, disabled ? stylesHook.feeModalItemDisabled : stylesHook.feeModalTime]}>
<Text style={stylesHook.feeModalTimeText}>~{time}</Text>
</View>
</View>
<View style={styles.feeModalRow}>
<Text style={disabled ? stylesHook.feeModalItemTextDisabled : stylesHook.feeModalValue}>{fee && formatFee(fee)}</Text>
<Text style={disabled ? stylesHook.feeModalItemTextDisabled : stylesHook.feeModalValue}>
{rate} {loc.units.sat_vbyte}
</Text>
</View>
</TouchableOpacity>
))}
<BottomModal
ref={feeModalRef}
backgroundColor={colors.modal}
contentContainerStyle={styles.modalContent}
footerDefaultMargins
footer={
<TouchableOpacity
testID="feeCustom"
accessibilityRole="button"
style={styles.feeModalCustom}
onPress={async () => {
let error = loc.send.fee_satvbyte;
while (true) {
@ -1316,7 +1281,34 @@ const SendDetails = () => {
>
<Text style={[styles.feeModalCustomText, stylesHook.feeModalCustomText]}>{loc.send.fee_custom}</Text>
</TouchableOpacity>
</View>
}
>
{options.map(({ label, time, fee, rate, active, disabled }) => (
<TouchableOpacity
accessibilityRole="button"
key={label}
disabled={disabled}
onPress={() => {
setFeePrecalc(fp => ({ ...fp, current: fee }));
feeModalRef.current?.dismiss();
setCustomFee(rate.toString());
}}
style={[styles.feeModalItem, active && styles.feeModalItemActive, active && !disabled && stylesHook.feeModalItemActive]}
>
<View style={styles.feeModalRow}>
<Text style={[styles.feeModalLabel, disabled ? stylesHook.feeModalItemTextDisabled : stylesHook.feeModalLabel]}>{label}</Text>
<View style={[styles.feeModalTime, disabled ? stylesHook.feeModalItemDisabled : stylesHook.feeModalTime]}>
<Text style={stylesHook.feeModalTimeText}>~{time}</Text>
</View>
</View>
<View style={styles.feeModalRow}>
<Text style={disabled ? stylesHook.feeModalItemTextDisabled : stylesHook.feeModalValue}>{fee && formatFee(fee)}</Text>
<Text style={disabled ? stylesHook.feeModalItemTextDisabled : stylesHook.feeModalValue}>
{rate} {loc.units.sat_vbyte}
</Text>
</View>
</TouchableOpacity>
))}
</BottomModal>
);
};
@ -1325,12 +1317,7 @@ const SendDetails = () => {
const isSendMaxUsed = addresses.some(element => element.amount === BitcoinUnit.MAX);
return (
<BottomModal
ref={optionsModalRef}
onClose={hideOptions}
backgroundColor={colors.modal}
contentContainerStyle={[styles.optionsContent, stylesHook.optionsContent]}
>
<BottomModal ref={optionsModalRef} onClose={hideOptions} backgroundColor={colors.modal} contentContainerStyle={styles.optionsContent}>
{wallet?.allowBIP47() && wallet.isBIP47Enabled() && (
<ListItem testID="InsertContactButton" title={loc.send.details_insert_contact} onPress={handleInsertContact} />
)}
@ -1666,7 +1653,7 @@ const styles = StyleSheet.create({
right: 8,
},
modalContent: {
padding: 22,
margin: 22,
},
optionsContent: {
padding: 22,
@ -1693,11 +1680,6 @@ const styles = StyleSheet.create({
paddingHorizontal: 6,
paddingVertical: 3,
},
feeModalCustom: {
height: 60,
alignItems: 'center',
justifyContent: 'center',
},
feeModalCustomText: {
fontSize: 15,
fontWeight: '600',

View file

@ -103,7 +103,12 @@ const WalletsAddMultisig = () => {
const renderModal = () => {
return (
<BottomModal sizes={['auto', 'large']} ref={bottomModalRef} contentContainerStyle={styles.modalContentShort} backgroundColor={stylesHook.modalContentShort}>
<BottomModal
sizes={['auto', 'large']}
ref={bottomModalRef}
contentContainerStyle={styles.modalContentShort}
backgroundColor={stylesHook.modalContentShort}
>
<Text style={[styles.textHeader, stylesHook.textHeader]}>{loc.multisig.quorum_header}</Text>
<Text style={[styles.textSubtitle, stylesHook.textSubtitle]}>{loc.multisig.required_keys_out_of_total}</Text>
<View style={styles.rowCenter}>