From e9fa0fa80923d582ecf43e80e37cb3d9e8ac5931 Mon Sep 17 00:00:00 2001 From: Jon Tzeng Date: Fri, 20 Feb 2026 10:54:35 -0800 Subject: [PATCH 1/2] Fix lint warnings in SendFromFioRows --- eslint.config.mjs | 2 +- src/components/scenes/SendScene2.tsx | 2 +- src/components/themed/SendFromFioRows.tsx | 117 ++++++++++++---------- 3 files changed, 67 insertions(+), 54 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 8e895ac7505..dc6e9ef7eaa 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -364,7 +364,7 @@ export default [ 'src/components/themed/SearchFooter.tsx', 'src/components/themed/SelectableRow.tsx', - 'src/components/themed/SendFromFioRows.tsx', + 'src/components/themed/ShareButtons.tsx', 'src/components/themed/Slider.tsx', diff --git a/src/components/scenes/SendScene2.tsx b/src/components/scenes/SendScene2.tsx index 8173ff846c6..f8aa17178b3 100644 --- a/src/components/scenes/SendScene2.tsx +++ b/src/components/scenes/SendScene2.tsx @@ -931,7 +931,7 @@ const SendComponent = (props: Props): React.ReactElement => { return ( ['navigation'] selected: string memo: string memoError: string @@ -68,7 +74,10 @@ export class SendFromFioRowsComponent extends React.PureComponent< } } - static getDerivedStateFromProps(props: Props, state: LocalState) { + static getDerivedStateFromProps( + props: Props, + state: LocalState + ): Partial | null { const { fioAddresses, selected } = props const { prevFioAddresses } = state if (fioAddresses.length !== prevFioAddresses.length) { @@ -81,8 +90,8 @@ export class SendFromFioRowsComponent extends React.PureComponent< ({ name }) => name === selected ) if ( - fioAddress && - prevFioAddress && + fioAddress != null && + prevFioAddress != null && fioAddress.bundledTxs !== prevFioAddress.bundledTxs ) { return { @@ -93,49 +102,51 @@ export class SendFromFioRowsComponent extends React.PureComponent< return null } - componentDidMount() { + componentDidMount(): void { const { fioRequest, isSendUsingFioAddress, refreshAllFioAddresses } = this.props - if (fioRequest != null || isSendUsingFioAddress) refreshAllFioAddresses() - if (fioRequest) { - this.setFioAddress(fioRequest.payer_fio_address).catch(err => { + if (fioRequest != null || isSendUsingFioAddress === true) + refreshAllFioAddresses() + if (fioRequest != null) { + this.setFioAddress(fioRequest.payer_fio_address).catch((err: unknown) => { showError(err) }) - } else if (isSendUsingFioAddress) { - this.setDefaultFioAddress().catch(err => { + } else if (isSendUsingFioAddress === true) { + this.setDefaultFioAddress().catch((err: unknown) => { showError(err) }) } } - componentDidUpdate(prevProps: Props) { + componentDidUpdate(prevProps: Props): void { const { fioRequest, isSendUsingFioAddress } = this.props const { bundledTxsUpdated } = this.state if (bundledTxsUpdated) { this.setState({ bundledTxsUpdated: false }) - this.setFioAddress(this.props.selected).catch(err => { + this.setFioAddress(this.props.selected).catch((err: unknown) => { showError(err) }) } if ( isSendUsingFioAddress !== prevProps.isSendUsingFioAddress && - !fioRequest && - isSendUsingFioAddress + fioRequest == null && + isSendUsingFioAddress === true ) { - this.setDefaultFioAddress().catch(err => { + this.setDefaultFioAddress().catch((err: unknown) => { showError(err) }) } } - async setDefaultFioAddress() { + async setDefaultFioAddress(): Promise { const { fioWallets } = this.props this.setState({ loading: true }) for (const fioWallet of fioWallets) { - const fioNames = await fioWallet.otherMethods.getFioAddressNames() - if (fioNames.length) { + const fioNames: string[] = + await fioWallet.otherMethods.getFioAddressNames() + if (fioNames.length > 0) { this.setState({ loading: false }, () => { - this.setFioAddress(fioNames[0], fioWallet).catch(err => { + this.setFioAddress(fioNames[0], fioWallet).catch((err: unknown) => { showError(err) }) }) @@ -144,7 +155,7 @@ export class SendFromFioRowsComponent extends React.PureComponent< } } - selectAddress = async () => { + selectAddress = async (): Promise => { const { currencyCode, coreWallet } = this.props const response = await Airship.show(bridge => ( )) - if (response) { + if (response != null && response !== '') { await this.setFioAddress(response) } } - openMessageInput = async () => { + handleOpenMessageInput = async (): Promise => { const memo = await Airship.show(bridge => ( { + ): Promise => { const { navigation, fioWallets, fioAddresses, fioRequest, currencyCode } = this.props - if (!fioWallet) { - if (fioAddresses && fioAddress.length) { + let resolvedWallet = fioWallet + if (resolvedWallet == null) { + if (fioAddresses != null && fioAddress.length > 0) { const selectedFioAddress = fioAddresses.find( ({ name }) => name === fioAddress ) - if (selectedFioAddress) { - fioWallet = fioWallets.find( + if (selectedFioAddress != null) { + resolvedWallet = fioWallets.find( ({ id }) => id === selectedFioAddress.walletId ) } } - fioWallet ??= await findWalletByFioAddress(fioWallets, fioAddress) + resolvedWallet ??= await findWalletByFioAddress(fioWallets, fioAddress) } let error = '' - if (!fioWallet) { + if (resolvedWallet == null) { error = lstrings.fio_select_address_no_wallet_err showError(error) return @@ -205,11 +217,12 @@ export class SendFromFioRowsComponent extends React.PureComponent< try { if (fioRequest != null || currencyCode === FIO_STR) { - await checkRecordSendFee(fioWallet, fioAddress) + await checkRecordSendFee(resolvedWallet, fioAddress) } - } catch (e: any) { - if (e.code && e.code === FIO_NO_BUNDLED_ERR_CODE) { - this.props.onSelect(fioAddress, fioWallet, e.message) + } catch (e: unknown) { + const bundledError = asMaybe(asFioBundledError)(e) + if (bundledError != null) { + this.props.onSelect(fioAddress, resolvedWallet, bundledError.message) const answer = await Airship.show<'ok' | 'cancel' | undefined>( bridge => ( { + handleMemoChange = (memo: string): void => { let memoError = '' - if (memo && memo.length > 64) { + if (memo !== '' && memo.length > 64) { memoError = lstrings.send_fio_request_error_memo_inline } - if (memo && !/^[\x20-\x7E]*$/.test(memo)) { + if (memo !== '' && !/^[\x20-\x7E]*$/.test(memo)) { memoError = lstrings.send_fio_request_error_memo_invalid_character } this.props.onMemoChange(memo, memoError) } - renderFioFromAddress() { + renderFioFromAddress(): React.ReactElement { const { fioRequest, selected } = this.props const { loading } = this.state return ( ) } - renderFioMemo() { + renderFioMemo(): React.ReactElement | null { const { memo, memoError, theme } = this.props const { loading } = this.state @@ -274,12 +287,12 @@ export class SendFromFioRowsComponent extends React.PureComponent< return null } - if (memoError) { + if (memoError !== '') { return ( {memoError} @@ -290,16 +303,16 @@ export class SendFromFioRowsComponent extends React.PureComponent< ) } - render() { + render(): React.ReactElement | null { const { fioRequest, isSendUsingFioAddress } = this.props - if (!fioRequest && !isSendUsingFioAddress) { + if (fioRequest == null && isSendUsingFioAddress !== true) { return null } From 0275afdfbccbb8af53d2067edcf776f88c48d248 Mon Sep 17 00:00:00 2001 From: Jon Tzeng Date: Fri, 20 Feb 2026 09:55:40 -0800 Subject: [PATCH 2/2] Disable autocorrect by default in text inputs Change SimpleTextInput and FilledTextInput to default autoCorrect to false instead of true. This prevents automatic acceptance of autocorrect suggestions when users interact with search bars and other text inputs. LogsModal explicitly sets autoCorrect={true} to preserve autocorrect for user message composition. --- CHANGELOG.md | 1 + .../modals/__snapshots__/CategoryModal.test.tsx.snap | 2 ++ .../modals/__snapshots__/PasswordReminderModal.test.tsx.snap | 1 + .../modals/__snapshots__/TextInputModal.test.tsx.snap | 2 ++ .../modals/__snapshots__/WalletListModal.test.tsx.snap | 1 + src/components/modals/SurveyModal.tsx | 2 ++ src/components/themed/FilledTextInput.tsx | 4 ++-- src/components/themed/SendFromFioRows.tsx | 2 +- src/components/themed/SimpleTextInput.tsx | 4 ++-- 9 files changed, 14 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e47b54e4d6e..44b3466f5da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ - fixed: Missing 2-factor approve / deny scene on login - fixed: Security check notification not reappearing after dismissal - fixed: Fix incorrect Moonpay buy tracking values caused by deeplink handler overwrite +- fixed: Search bars automatically accepting autocorrect suggestions ## 4.43.1 (2025-02-13) diff --git a/src/__tests__/modals/__snapshots__/CategoryModal.test.tsx.snap b/src/__tests__/modals/__snapshots__/CategoryModal.test.tsx.snap index af807184a4f..cbfa3fb4723 100644 --- a/src/__tests__/modals/__snapshots__/CategoryModal.test.tsx.snap +++ b/src/__tests__/modals/__snapshots__/CategoryModal.test.tsx.snap @@ -848,6 +848,7 @@ exports[`CategoryModal should render with a subcategory 1`] = ` accessible={true} allowFontScaling={false} autoCapitalize="words" + autoCorrect={false} autoFocus={true} collapsable={false} defaultValue="Paycheck" @@ -2570,6 +2571,7 @@ exports[`CategoryModal should render with an empty subcategory 1`] = ` accessible={true} allowFontScaling={false} autoCapitalize="words" + autoCorrect={false} autoFocus={true} collapsable={false} defaultValue="" diff --git a/src/__tests__/modals/__snapshots__/PasswordReminderModal.test.tsx.snap b/src/__tests__/modals/__snapshots__/PasswordReminderModal.test.tsx.snap index e7592ba1356..766b4f97fb7 100644 --- a/src/__tests__/modals/__snapshots__/PasswordReminderModal.test.tsx.snap +++ b/src/__tests__/modals/__snapshots__/PasswordReminderModal.test.tsx.snap @@ -612,6 +612,7 @@ Please enter your password below. A successful verification will prevent this wa accessible={true} allowFontScaling={false} autoCapitalize="none" + autoCorrect={false} autoFocus={false} collapsable={false} defaultValue="" diff --git a/src/__tests__/modals/__snapshots__/TextInputModal.test.tsx.snap b/src/__tests__/modals/__snapshots__/TextInputModal.test.tsx.snap index de5210c0260..57fdb3f2886 100644 --- a/src/__tests__/modals/__snapshots__/TextInputModal.test.tsx.snap +++ b/src/__tests__/modals/__snapshots__/TextInputModal.test.tsx.snap @@ -505,6 +505,7 @@ exports[`TextInputModal should render with a blank input field 1`] = ` } accessible={true} allowFontScaling={false} + autoCorrect={false} autoFocus={true} collapsable={false} defaultValue="" @@ -1357,6 +1358,7 @@ exports[`TextInputModal should render with a populated input field 1`] = ` } accessible={true} allowFontScaling={false} + autoCorrect={false} autoFocus={true} collapsable={false} defaultValue="initialValue" diff --git a/src/__tests__/modals/__snapshots__/WalletListModal.test.tsx.snap b/src/__tests__/modals/__snapshots__/WalletListModal.test.tsx.snap index 42e8526ef3d..25d2c135ddc 100644 --- a/src/__tests__/modals/__snapshots__/WalletListModal.test.tsx.snap +++ b/src/__tests__/modals/__snapshots__/WalletListModal.test.tsx.snap @@ -527,6 +527,7 @@ exports[`WalletListModal should render with loading props 1`] = ` } accessible={true} allowFontScaling={false} + autoCorrect={false} autoFocus={false} collapsable={false} defaultValue="" diff --git a/src/components/modals/SurveyModal.tsx b/src/components/modals/SurveyModal.tsx index ae5fbc58080..0da0236ef74 100644 --- a/src/components/modals/SurveyModal.tsx +++ b/src/components/modals/SurveyModal.tsx @@ -189,6 +189,7 @@ export const SurveyModal: React.FC = props => { ))} => { const memo = await Airship.show(bridge => ( )) if (memo != null) this.handleMemoChange(memo) diff --git a/src/components/themed/SimpleTextInput.tsx b/src/components/themed/SimpleTextInput.tsx index d07855e3249..1c167b604b2 100644 --- a/src/components/themed/SimpleTextInput.tsx +++ b/src/components/themed/SimpleTextInput.tsx @@ -56,7 +56,7 @@ export interface SimpleTextInputProps extends LayoutStyleProps { // Other React Native TextInput properties: autoCapitalize?: 'none' | 'sentences' | 'words' | 'characters' // Defaults to 'sentences' - autoCorrect?: boolean // Defaults to 'true' + autoCorrect?: boolean // Defaults to 'false' blurOnSubmit?: boolean // Defaults to 'true' keyboardType?: | 'default' @@ -124,7 +124,7 @@ export const SimpleTextInput = React.forwardRef< // TextInput: autoCapitalize = props.secureTextEntry === true ? 'none' : undefined, - autoCorrect, + autoCorrect = false, autoFocus = false, blurOnClear = false, blurOnSubmit = false,