REF: InputAccessories to TSX

This commit is contained in:
Marcos Rodriguez Velez 2024-08-24 14:06:17 -04:00
parent 6e2cd06461
commit 8ba76fca29
11 changed files with 143 additions and 125 deletions

View File

@ -1,22 +1,8 @@
/* eslint react/prop-types: "off", react-native/no-inline-styles: "off" */
import Clipboard from '@react-native-clipboard/clipboard';
import React, { forwardRef } from 'react';
import {
ActivityIndicator,
Dimensions,
I18nManager,
InputAccessoryView,
Keyboard,
Platform,
StyleSheet,
TextInput,
TouchableOpacity,
View,
} from 'react-native';
import { ActivityIndicator, Dimensions, I18nManager, Platform, StyleSheet, TextInput, TouchableOpacity, View } from 'react-native';
import { Icon, Text } from '@rneui/themed';
import { useTheme } from './components/themes';
import loc from './loc';
const { height, width } = Dimensions.get('window');
const aspectRatio = height / width;
@ -137,60 +123,6 @@ export const BlueSpacing10 = props => {
return <View {...props} style={{ height: 10, opacity: 0 }} />;
};
export const BlueDismissKeyboardInputAccessory = () => {
const { colors } = useTheme();
BlueDismissKeyboardInputAccessory.InputAccessoryViewID = 'BlueDismissKeyboardInputAccessory';
return Platform.OS !== 'ios' ? null : (
<InputAccessoryView nativeID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}>
<View
style={{
backgroundColor: colors.inputBackgroundColor,
height: 44,
flex: 1,
flexDirection: 'row',
justifyContent: 'flex-end',
alignItems: 'center',
}}
>
<BlueButtonLink title={loc.send.input_done} onPress={Keyboard.dismiss} />
</View>
</InputAccessoryView>
);
};
export const BlueDoneAndDismissKeyboardInputAccessory = props => {
const { colors } = useTheme();
BlueDoneAndDismissKeyboardInputAccessory.InputAccessoryViewID = 'BlueDoneAndDismissKeyboardInputAccessory';
const onPasteTapped = async () => {
const clipboard = await Clipboard.getString();
props.onPasteTapped(clipboard);
};
const inputView = (
<View
style={{
backgroundColor: colors.inputBackgroundColor,
flexDirection: 'row',
justifyContent: 'flex-end',
alignItems: 'center',
maxHeight: 44,
}}
>
<BlueButtonLink title={loc.send.input_clear} onPress={props.onClearTapped} />
<BlueButtonLink title={loc.send.input_paste} onPress={onPasteTapped} />
<BlueButtonLink title={loc.send.input_done} onPress={Keyboard.dismiss} />
</View>
);
if (Platform.OS === 'ios') {
return <InputAccessoryView nativeID={BlueDoneAndDismissKeyboardInputAccessory.InputAccessoryViewID}>{inputView}</InputAccessoryView>;
} else {
return inputView;
}
};
export const BlueLoading = props => {
return (
<View style={{ flex: 1, justifyContent: 'center' }} {...props}>

View File

@ -0,0 +1,36 @@
import React from 'react';
import { InputAccessoryView, Keyboard, Platform, StyleSheet, View } from 'react-native';
import { useTheme } from './themes';
import { BlueButtonLink } from '../BlueComponents';
import loc from '../loc';
export const DismissKeyboardInputAccessoryViewID = 'DismissKeyboardInputAccessory';
export const DismissKeyboardInputAccessory: React.FC = () => {
const { colors } = useTheme();
const styleHooks = StyleSheet.create({
container: {
backgroundColor: colors.inputBackgroundColor,
},
});
if (Platform.OS !== 'ios') {
return null;
}
return (
<InputAccessoryView nativeID={DismissKeyboardInputAccessoryViewID}>
<View style={[styles.container, styleHooks.container]}>
<BlueButtonLink title={loc.send.input_done} onPress={Keyboard.dismiss} />
</View>
</InputAccessoryView>
);
};
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
justifyContent: 'flex-end',
alignItems: 'center',
maxHeight: 44,
},
});

View File

@ -0,0 +1,49 @@
import React from 'react';
import { InputAccessoryView, Keyboard, Platform, StyleSheet, View } from 'react-native';
import { BlueButtonLink } from '../BlueComponents';
import loc from '../loc';
import { useTheme } from './themes';
import Clipboard from '@react-native-clipboard/clipboard';
interface DoneAndDismissKeyboardInputAccessoryProps {
onPasteTapped: (clipboard: string) => void;
onClearTapped: () => void;
}
export const DoneAndDismissKeyboardInputAccessoryViewID = 'DoneAndDismissKeyboardInputAccessory';
export const DoneAndDismissKeyboardInputAccessory: React.FC<DoneAndDismissKeyboardInputAccessoryProps> = props => {
const { colors } = useTheme();
const styleHooks = StyleSheet.create({
container: {
backgroundColor: colors.inputBackgroundColor,
},
});
const onPasteTapped = async () => {
const clipboard = await Clipboard.getString();
props.onPasteTapped(clipboard);
};
const inputView = (
<View style={[styles.container, styleHooks.container]}>
<BlueButtonLink title={loc.send.input_clear} onPress={props.onClearTapped} />
<BlueButtonLink title={loc.send.input_paste} onPress={onPasteTapped} />
<BlueButtonLink title={loc.send.input_done} onPress={Keyboard.dismiss} />
</View>
);
if (Platform.OS === 'ios') {
return <InputAccessoryView nativeID={DoneAndDismissKeyboardInputAccessoryViewID}>{inputView}</InputAccessoryView>;
} else {
return inputView;
}
};
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
justifyContent: 'flex-end',
alignItems: 'center',
maxHeight: 44,
},
});

View File

@ -1,14 +1,18 @@
import PropTypes from 'prop-types';
import React from 'react';
import { InputAccessoryView, Keyboard, Platform, StyleSheet, View } from 'react-native';
import { Text } from '@rneui/themed';
import { BlueButtonLink } from '../BlueComponents';
import loc from '../loc';
import { BitcoinUnit } from '../models/bitcoinUnits';
import { useTheme } from './themes';
const InputAccessoryAllFunds = ({ balance, canUseAll, onUseAllPressed }) => {
interface InputAccessoryAllFundsProps {
balance: string;
canUseAll: boolean;
onUseAllPressed: () => void;
}
const InputAccessoryAllFunds: React.FC<InputAccessoryAllFundsProps> = ({ balance, canUseAll, onUseAllPressed }) => {
const { colors } = useTheme();
const stylesHook = StyleSheet.create({
@ -42,7 +46,7 @@ const InputAccessoryAllFunds = ({ balance, canUseAll, onUseAllPressed }) => {
);
if (Platform.OS === 'ios') {
return <InputAccessoryView nativeID={InputAccessoryAllFunds.InputAccessoryViewID}>{inputView}</InputAccessoryView>;
return <InputAccessoryView nativeID={InputAccessoryAllFundsAccessoryViewID}>{inputView}</InputAccessoryView>;
}
// androidPlaceholder View is needed to force shrink screen (KeyboardAvoidingView) where this component is used
@ -54,13 +58,7 @@ const InputAccessoryAllFunds = ({ balance, canUseAll, onUseAllPressed }) => {
);
};
InputAccessoryAllFunds.InputAccessoryViewID = 'useMaxInputAccessoryViewID';
InputAccessoryAllFunds.propTypes = {
balance: PropTypes.string.isRequired,
canUseAll: PropTypes.bool.isRequired,
onUseAllPressed: PropTypes.func.isRequired,
};
export const InputAccessoryAllFundsAccessoryViewID = 'useMaxInputAccessoryViewID';
const styles = StyleSheet.create({
root: {

View File

@ -18,7 +18,7 @@ import { parse } from 'url'; // eslint-disable-line n/no-deprecated-api
import { btcToSatoshi, fiatToBTC, satoshiToBTC } from '../../blue_modules/currency';
import triggerHapticFeedback, { HapticFeedbackTypes } from '../../blue_modules/hapticFeedback';
import Notifications from '../../blue_modules/notifications';
import { BlueDismissKeyboardInputAccessory, BlueLoading } from '../../BlueComponents';
import { BlueLoading } from '../../BlueComponents';
import Lnurl from '../../class/lnurl';
import presentAlert from '../../components/Alert';
import AmountInput from '../../components/AmountInput';
@ -30,6 +30,7 @@ import loc, { formatBalance, formatBalancePlain, formatBalanceWithoutSuffix } fr
import { BitcoinUnit, Chain } from '../../models/bitcoinUnits';
import * as NavigationService from '../../NavigationService';
import { useStorage } from '../../hooks/context/useStorage';
import { DismissKeyboardInputAccessory, DismissKeyboardInputAccessoryViewID } from '../../components/DismissKeyboardInputAccessory';
const LNDCreateInvoice = () => {
const { wallets, saveToDisk, setSelectedWalletID } = useStorage();
@ -403,7 +404,7 @@ const LNDCreateInvoice = () => {
onChangeText={setAmount}
disabled={isLoading || (lnurlParams && lnurlParams.fixed)}
unit={unit}
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
inputAccessoryViewID={DismissKeyboardInputAccessoryViewID}
/>
<View style={[styles.fiat, styleHooks.fiat]}>
<TextInput
@ -415,11 +416,11 @@ const LNDCreateInvoice = () => {
style={styles.fiat2}
editable={!isLoading}
onSubmitEditing={Keyboard.dismiss}
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
inputAccessoryViewID={DismissKeyboardInputAccessoryViewID}
/>
{lnurlParams ? null : renderScanClickable()}
</View>
<BlueDismissKeyboardInputAccessory />
<DismissKeyboardInputAccessory />
{renderCreateButton()}
</View>
{renderWalletSelectionButton()}

View File

@ -5,7 +5,7 @@ import { I18nManager, Image, ScrollView, StyleSheet, Text, TouchableOpacity, Vie
import { Icon } from '@rneui/themed';
import { btcToSatoshi, fiatToBTC, satoshiToBTC, satoshiToLocalCurrency } from '../../blue_modules/currency';
import triggerHapticFeedback, { HapticFeedbackTypes } from '../../blue_modules/hapticFeedback';
import { BlueCard, BlueDismissKeyboardInputAccessory, BlueLoading, BlueSpacing20, BlueText } from '../../BlueComponents';
import { BlueCard, BlueLoading, BlueSpacing20, BlueText } from '../../BlueComponents';
import Lnurl from '../../class/lnurl';
import presentAlert from '../../components/Alert';
import AmountInput from '../../components/AmountInput';
@ -18,6 +18,7 @@ import loc, { formatBalance, formatBalanceWithoutSuffix } from '../../loc';
import { BitcoinUnit, Chain } from '../../models/bitcoinUnits';
import { useStorage } from '../../hooks/context/useStorage';
import { useExtendedNavigation } from '../../hooks/useExtendedNavigation';
import { DismissKeyboardInputAccessory, DismissKeyboardInputAccessoryViewID } from '../../components/DismissKeyboardInputAccessory';
/**
* if user has default currency - fiat, attempting to pay will trigger conversion from entered in input field fiat value
@ -207,8 +208,9 @@ const LnurlPay = () => {
onChangeText={setAmount}
disabled={payload && payload.fixed}
unit={unit}
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
inputAccessoryViewID={DismissKeyboardInputAccessoryViewID}
/>
<DismissKeyboardInputAccessory />
<BlueText style={styles.alignSelfCenter}>
{loc.formatString(loc.lndViewInvoice.please_pay_between_and, {
min: formatBalance(payload?.min, unit),

View File

@ -5,7 +5,7 @@ import { Icon } from '@rneui/themed';
import { btcToSatoshi, fiatToBTC } from '../../blue_modules/currency';
import triggerHapticFeedback, { HapticFeedbackTypes } from '../../blue_modules/hapticFeedback';
import { BlueCard, BlueDismissKeyboardInputAccessory, BlueLoading } from '../../BlueComponents';
import { BlueCard, BlueLoading } from '../../BlueComponents';
import Lnurl from '../../class/lnurl';
import AddressInput from '../../components/AddressInput';
import presentAlert from '../../components/Alert';
@ -17,6 +17,7 @@ import { useBiometrics, unlockWithBiometrics } from '../../hooks/useBiometrics';
import loc, { formatBalanceWithoutSuffix } from '../../loc';
import { BitcoinUnit, Chain } from '../../models/bitcoinUnits';
import { useStorage } from '../../hooks/context/useStorage';
import { DismissKeyboardInputAccessory, DismissKeyboardInputAccessoryViewID } from '../../components/DismissKeyboardInputAccessory';
const ScanLndInvoice = () => {
const { wallets, fetchAndSaveWalletTransactions } = useStorage();
@ -307,7 +308,7 @@ const ScanLndInvoice = () => {
onChangeText={setAmount}
disabled={!decoded || isLoading || decoded.num_satoshis > 0}
unit={unit}
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
inputAccessoryViewID={DismissKeyboardInputAccessoryViewID}
/>
</View>
@ -321,7 +322,7 @@ const ScanLndInvoice = () => {
address={destination}
isLoading={isLoading}
placeholder={loc.lnd.placeholder}
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
inputAccessoryViewID={DismissKeyboardInputAccessoryViewID}
launchedBy={name}
onBlur={onBlur}
keyboardType="email-address"
@ -355,7 +356,7 @@ const ScanLndInvoice = () => {
{renderWalletSelectionButton()}
</ScrollView>
</View>
<BlueDismissKeyboardInputAccessory />
<DismissKeyboardInputAccessory />
</SafeArea>
);
};

View File

@ -27,7 +27,7 @@ import RNFS from 'react-native-fs';
import { btcToSatoshi, fiatToBTC } from '../../blue_modules/currency';
import * as fs from '../../blue_modules/fs';
import triggerHapticFeedback, { HapticFeedbackTypes } from '../../blue_modules/hapticFeedback';
import { BlueDismissKeyboardInputAccessory, BlueText } from '../../BlueComponents';
import { BlueText } from '../../BlueComponents';
import { HDSegwitBech32Wallet, MultisigHDWallet, WatchOnlyWallet } from '../../class';
import DeeplinkSchemaMatch from '../../class/deeplink-schema-match';
import { AbstractHDElectrumWallet } from '../../class/wallets/abstract-hd-electrum-wallet';
@ -37,7 +37,7 @@ import AmountInput from '../../components/AmountInput';
import { BottomModalHandle } from '../../components/BottomModal';
import Button from '../../components/Button';
import CoinsSelected from '../../components/CoinsSelected';
import InputAccessoryAllFunds from '../../components/InputAccessoryAllFunds';
import InputAccessoryAllFunds, { InputAccessoryAllFundsAccessoryViewID } from '../../components/InputAccessoryAllFunds';
import { useTheme } from '../../components/themes';
import ToolTipMenu from '../../components/TooltipMenu';
import { requestCameraAuthorization, scanQrHelper } from '../../helpers/scan-qr';
@ -55,6 +55,7 @@ import { useStorage } from '../../hooks/context/useStorage';
import { Action } from '../../components/types';
import SelectFeeModal from '../../components/SelectFeeModal';
import { useKeyboard } from '../../hooks/useKeyboard';
import { DismissKeyboardInputAccessory, DismissKeyboardInputAccessoryViewID } from '../../components/DismissKeyboardInputAccessory';
interface IPaymentDestinations {
address: string; // btc address or payment code
@ -1265,7 +1266,7 @@ const SendDetails = () => {
unit={units[index] || amountUnit}
editable={isEditable}
disabled={!isEditable}
inputAccessoryViewID={InputAccessoryAllFunds.InputAccessoryViewID}
inputAccessoryViewID={InputAccessoryAllFundsAccessoryViewID}
/>
{frozenBalance > 0 && (
@ -1342,7 +1343,7 @@ const SendDetails = () => {
editable={!isLoading}
onSubmitEditing={Keyboard.dismiss}
/* @ts-ignore marcos fixme */
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
inputAccessoryViewID={DismissKeyboardInputAccessoryViewID}
/>
</View>
<TouchableOpacity
@ -1375,7 +1376,7 @@ const SendDetails = () => {
feeUnit={feeUnit || BitcoinUnit.BTC}
/>
</View>
<BlueDismissKeyboardInputAccessory />
<DismissKeyboardInputAccessory />
{Platform.select({
ios: <InputAccessoryAllFunds canUseAll={balance > 0} onUseAllPressed={onUseAllPressed} balance={String(allBalance)} />,
android: isAmountToolbarVisibleForAndroid && (

View File

@ -17,15 +17,7 @@ import {
import DefaultPreference from 'react-native-default-preference';
import * as BlueElectrum from '../../blue_modules/BlueElectrum';
import triggerHapticFeedback, { HapticFeedbackTypes } from '../../blue_modules/hapticFeedback';
import {
BlueButtonLink,
BlueCard,
BlueDismissKeyboardInputAccessory,
BlueDoneAndDismissKeyboardInputAccessory,
BlueLoading,
BlueSpacing20,
BlueText,
} from '../../BlueComponents';
import { BlueButtonLink, BlueCard, BlueLoading, BlueSpacing20, BlueText } from '../../BlueComponents';
import DeeplinkSchemaMatch from '../../class/deeplink-schema-match';
import presentAlert, { AlertType } from '../../components/Alert';
import Button from '../../components/Button';
@ -34,6 +26,11 @@ import { BlueCurrentTheme } from '../../components/themes';
import { scanQrHelper } from '../../helpers/scan-qr';
import loc from '../../loc';
import { StorageContext } from '../../components/Context/StorageProvider';
import {
DoneAndDismissKeyboardInputAccessory,
DoneAndDismissKeyboardInputAccessoryViewID,
} from '../../components/DoneAndDismissKeyboardInputAccessory';
import { DismissKeyboardInputAccessory, DismissKeyboardInputAccessoryViewID } from '../../components/DismissKeyboardInputAccessory';
export default class ElectrumSettings extends Component {
static contextType = StorageContext;
@ -303,7 +300,7 @@ export default class ElectrumSettings extends Component {
autoCorrect={false}
autoCapitalize="none"
underlineColorAndroid="transparent"
inputAccessoryViewID={BlueDoneAndDismissKeyboardInputAccessory.InputAccessoryViewID}
inputAccessoryViewID={DoneAndDismissKeyboardInputAccessoryViewID}
testID="HostInput"
onFocus={() => this.setState({ isAndroidAddressKeyboardVisible: true })}
onBlur={() => this.setState({ isAndroidAddressKeyboardVisible: false })}
@ -332,7 +329,7 @@ export default class ElectrumSettings extends Component {
autoCorrect={false}
autoCapitalize="none"
keyboardType="number-pad"
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
inputAccessoryViewID={DismissKeyboardInputAccessoryViewID}
testID="PortInput"
onFocus={() => this.setState({ isAndroidNumericKeyboardFocused: true })}
onBlur={() => this.setState({ isAndroidNumericKeyboardFocused: false })}
@ -361,13 +358,13 @@ export default class ElectrumSettings extends Component {
<BlueSpacing20 />
</BlueCard>
{Platform.select({
ios: <BlueDismissKeyboardInputAccessory />,
android: this.state.isAndroidNumericKeyboardFocused && <BlueDismissKeyboardInputAccessory />,
ios: <DismissKeyboardInputAccessory />,
android: this.state.isAndroidNumericKeyboardFocused && <DismissKeyboardInputAccessory />,
})}
{Platform.select({
ios: (
<BlueDoneAndDismissKeyboardInputAccessory
<DoneAndDismissKeyboardInputAccessory
onClearTapped={() => this.setState({ host: '' })}
onPasteTapped={text => {
this.setState({ host: text });
@ -376,7 +373,7 @@ export default class ElectrumSettings extends Component {
/>
),
android: this.state.isAndroidAddressKeyboardVisible && (
<BlueDoneAndDismissKeyboardInputAccessory
<DoneAndDismissKeyboardInputAccessory
onClearTapped={() => {
this.setState({ host: '' });
Keyboard.dismiss();

View File

@ -2,14 +2,7 @@ import { useNavigation, useRoute } from '@react-navigation/native';
import React, { useEffect, useState } from 'react';
import { Keyboard, Platform, StyleSheet, Switch, TouchableWithoutFeedback, View } from 'react-native';
import {
BlueButtonLink,
BlueDoneAndDismissKeyboardInputAccessory,
BlueFormLabel,
BlueFormMultiInput,
BlueSpacing20,
BlueText,
} from '../../BlueComponents';
import { BlueButtonLink, BlueFormLabel, BlueFormMultiInput, BlueSpacing20, BlueText } from '../../BlueComponents';
import Button from '../../components/Button';
import SafeArea from '../../components/SafeArea';
import { useTheme } from '../../components/themes';
@ -17,6 +10,10 @@ import { requestCameraAuthorization } from '../../helpers/scan-qr';
import usePrivacy from '../../hooks/usePrivacy';
import loc from '../../loc';
import { useSettings } from '../../hooks/context/useSettings';
import {
DoneAndDismissKeyboardInputAccessory,
DoneAndDismissKeyboardInputAccessoryViewID,
} from '../../components/DoneAndDismissKeyboardInputAccessory';
const WalletsImport = () => {
const navigation = useNavigation();
@ -168,13 +165,13 @@ const WalletsImport = () => {
onBlur={onBlur}
onChangeText={setImportText}
testID="MnemonicInput"
inputAccessoryViewID={BlueDoneAndDismissKeyboardInputAccessory.InputAccessoryViewID}
inputAccessoryViewID={DoneAndDismissKeyboardInputAccessoryViewID}
/>
{Platform.select({ android: !isToolbarVisibleForAndroid && renderOptionsAndImportButton, default: renderOptionsAndImportButton })}
{Platform.select({
ios: (
<BlueDoneAndDismissKeyboardInputAccessory
<DoneAndDismissKeyboardInputAccessory
onClearTapped={() => {
setImportText('');
}}
@ -185,7 +182,7 @@ const WalletsImport = () => {
/>
),
android: isToolbarVisibleForAndroid && (
<BlueDoneAndDismissKeyboardInputAccessory
<DoneAndDismissKeyboardInputAccessory
onClearTapped={() => {
setImportText('');
Keyboard.dismiss();

View File

@ -4,12 +4,16 @@ import { ActivityIndicator, Keyboard, LayoutAnimation, Platform, ScrollView, Sty
import { Icon } from '@rneui/themed';
import Share from 'react-native-share';
import triggerHapticFeedback, { HapticFeedbackTypes } from '../../blue_modules/hapticFeedback';
import { BlueDoneAndDismissKeyboardInputAccessory, BlueFormLabel, BlueSpacing10, BlueSpacing20, BlueSpacing40 } from '../../BlueComponents';
import { BlueFormLabel, BlueSpacing10, BlueSpacing20, BlueSpacing40 } from '../../BlueComponents';
import presentAlert from '../../components/Alert';
import { FButton, FContainer } from '../../components/FloatButtons';
import { useTheme } from '../../components/themes';
import loc from '../../loc';
import { useStorage } from '../../hooks/context/useStorage';
import {
DoneAndDismissKeyboardInputAccessory,
DoneAndDismissKeyboardInputAccessoryViewID,
} from '../../components/DoneAndDismissKeyboardInputAccessory';
const SignVerify = () => {
const { colors } = useTheme();
@ -161,7 +165,7 @@ const SignVerify = () => {
value={message}
onChangeText={setMessage}
testID="Message"
inputAccessoryViewID={BlueDoneAndDismissKeyboardInputAccessory.InputAccessoryViewID}
inputAccessoryViewID={DoneAndDismissKeyboardInputAccessoryViewID}
style={[styles.flex, styles.text, styles.textMessage, stylesHooks.text]}
autoCorrect={false}
autoCapitalize="none"
@ -201,7 +205,7 @@ const SignVerify = () => {
{Platform.select({
ios: (
<BlueDoneAndDismissKeyboardInputAccessory
<DoneAndDismissKeyboardInputAccessory
onClearTapped={() => setMessage('')}
onPasteTapped={text => {
setMessage(text);
@ -210,7 +214,7 @@ const SignVerify = () => {
/>
),
android: isToolbarVisibleForAndroid && (
<BlueDoneAndDismissKeyboardInputAccessory
<DoneAndDismissKeyboardInputAccessory
onClearTapped={() => {
setMessage('');
Keyboard.dismiss();