From b83915efc1bb12278f4a58ee3dbe2e9aa9bd0cb2 Mon Sep 17 00:00:00 2001 From: Filip Solecki Date: Mon, 15 Jan 2024 10:21:04 +0100 Subject: [PATCH] CR fixes --- src/components/AddressSearch/index.tsx | 32 ++++++++++++------- .../isCurrentTargetInsideContainer.native.ts | 8 ++--- .../isCurrentTargetInsideContainer.ts | 10 +++--- src/components/AddressSearch/types.ts | 7 ++-- .../BaseLocationErrorMessage.tsx | 2 +- .../LocationErrorMessage/index.native.tsx | 2 +- src/components/LocationErrorMessage/index.tsx | 2 +- src/components/LocationErrorMessage/types.ts | 6 ++-- 8 files changed, 42 insertions(+), 27 deletions(-) diff --git a/src/components/AddressSearch/index.tsx b/src/components/AddressSearch/index.tsx index 77ea553030e9..71fde0e42b7b 100644 --- a/src/components/AddressSearch/index.tsx +++ b/src/components/AddressSearch/index.tsx @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import React, {forwardRef, useCallback, useEffect, useMemo, useRef, useState} from 'react'; import type {ForwardedRef} from 'react'; import {ActivityIndicator, Keyboard, LogBox, ScrollView, Text, View} from 'react-native'; @@ -7,6 +6,7 @@ import {GooglePlacesAutocomplete} from 'react-native-google-places-autocomplete' import type {GooglePlaceData, GooglePlaceDetail} from 'react-native-google-places-autocomplete'; import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import LocationErrorMessage from '@components/LocationErrorMessage'; +import type {LocationErrorCodeType} from '@components/LocationErrorMessage/types'; import TextInput from '@components/TextInput'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; @@ -67,8 +67,9 @@ function AddressSearch( const [displayListViewBorder, setDisplayListViewBorder] = useState(false); const [isTyping, setIsTyping] = useState(false); const [isFocused, setIsFocused] = useState(false); - const [searchValue, setSearchValue] = useState(value ?? defaultValue ?? ''); - const [locationErrorCode, setLocationErrorCode] = useState(null); + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + const [searchValue, setSearchValue] = useState(value || defaultValue || ''); + const [locationErrorCode, setLocationErrorCode] = useState(null); const [isFetchingCurrentLocation, setIsFetchingCurrentLocation] = useState(false); const shouldTriggerGeolocationCallbacks = useRef(true); const containerRef = useRef(null); @@ -90,9 +91,9 @@ function AddressSearch( // amount of data massaging needs to happen for what the parent expects to get from this function. if (details) { onPress?.({ - address: autocompleteData.description, - lat: details.geometry.location.lat, - lng: details.geometry.location.lng, + address: autocompleteData.description ?? '', + lat: details.geometry.location.lat ?? 0, + lng: details.geometry.location.lng ?? 0, name: details.name, }); } @@ -112,14 +113,19 @@ function AddressSearch( administrative_area_level_2: stateFallback, country: countryPrimary, } = GooglePlacesUtils.getAddressComponents(addressComponents, { + // eslint-disable-next-line @typescript-eslint/naming-convention street_number: 'long_name', route: 'long_name', subpremise: 'long_name', locality: 'long_name', sublocality: 'long_name', + // eslint-disable-next-line @typescript-eslint/naming-convention postal_town: 'long_name', + // eslint-disable-next-line @typescript-eslint/naming-convention postal_code: 'long_name', + // eslint-disable-next-line @typescript-eslint/naming-convention administrative_area_level_1: 'short_name', + // eslint-disable-next-line @typescript-eslint/naming-convention administrative_area_level_2: 'long_name', country: 'short_name', }); @@ -127,6 +133,7 @@ function AddressSearch( // The state's iso code (short_name) is needed for the StatePicker component but we also // need the state's full name (long_name) when we render the state in a TextInput. const {administrative_area_level_1: longStateName} = GooglePlacesUtils.getAddressComponents(addressComponents, { + // eslint-disable-next-line @typescript-eslint/naming-convention administrative_area_level_1: 'long_name', }); @@ -140,7 +147,8 @@ function AddressSearch( const countryFallback = Object.keys(CONST.ALL_COUNTRIES).find((country) => country === countryFallbackLongName); - const country = countryPrimary ?? countryFallback ?? ''; + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + const country = countryPrimary || countryFallback || ''; const values = { street: `${streetNumber} ${streetName}`.trim(), @@ -159,7 +167,7 @@ function AddressSearch( lat: details.geometry.location.lat ?? 0, lng: details.geometry.location.lng ?? 0, - address: autocompleteData.description ?? details.formatted_address ?? '', + address: autocompleteData.description || details.formatted_address || '', }; // If the address is not in the US, use the full length state name since we're displaying the address's @@ -183,8 +191,8 @@ function AddressSearch( // We are setting up a fallback to ensure "values.street" is populated with a relevant value if (!values.street && details.adr_address) { const streetAddressRegex = /([^<]*)<\/span>/; - const adr_address = details.adr_address.match(streetAddressRegex); - const streetAddressFallback = adr_address ? adr_address?.[1] : null; + const adrAddress = details.adr_address.match(streetAddressRegex); + const streetAddressFallback = adrAddress ? adrAddress?.[1] : null; if (streetAddressFallback) { values.street = streetAddressFallback; } @@ -252,7 +260,7 @@ function AddressSearch( } setIsFetchingCurrentLocation(false); - setLocationErrorCode(errorData.code); + setLocationErrorCode(errorData.code as LocationErrorCodeType); }, { maximumAge: 0, // No cache, always get fresh location info @@ -288,7 +296,7 @@ function AddressSearch( const listEmptyComponent = useCallback( () => - !!isOffline && !!isTyping ? {translate('common.noResultsFound')} : null, + !!isOffline || !isTyping ? null : {translate('common.noResultsFound')}, [isOffline, isTyping, styles, translate], ); diff --git a/src/components/AddressSearch/isCurrentTargetInsideContainer.native.ts b/src/components/AddressSearch/isCurrentTargetInsideContainer.native.ts index dbf0004b08d9..b53b9e3ddec0 100644 --- a/src/components/AddressSearch/isCurrentTargetInsideContainer.native.ts +++ b/src/components/AddressSearch/isCurrentTargetInsideContainer.native.ts @@ -1,6 +1,6 @@ -function isCurrentTargetInsideContainer() { - // The related target check is not required here because in native there is no race condition rendering like on the web - return false; -} +import type {IsCurrentTargetInsideContainerType} from './types'; + +// The related target check is not required here because in native there is no race condition rendering like on the web +const isCurrentTargetInsideContainer: IsCurrentTargetInsideContainerType = () => false; export default isCurrentTargetInsideContainer; diff --git a/src/components/AddressSearch/isCurrentTargetInsideContainer.ts b/src/components/AddressSearch/isCurrentTargetInsideContainer.ts index d2f95a987994..a50eb747b400 100644 --- a/src/components/AddressSearch/isCurrentTargetInsideContainer.ts +++ b/src/components/AddressSearch/isCurrentTargetInsideContainer.ts @@ -1,12 +1,14 @@ -import type {RefObject} from 'react'; -import type {NativeSyntheticEvent, TextInputFocusEventData, View} from 'react-native'; +import type {IsCurrentTargetInsideContainerType} from './types'; -function isCurrentTargetInsideContainer(event: FocusEvent | NativeSyntheticEvent, containerRef: RefObject): boolean { +const isCurrentTargetInsideContainer: IsCurrentTargetInsideContainerType = (event, containerRef) => { + // The related target check is required here + // because without it when we select an option, the onBlur will still trigger setting displayListViewBorder to false + // it will make the auto complete component re-render before onPress is called making selecting an option not working. if (!containerRef.current || !event.target || !('relatedTarget' in event) || !('contains' in containerRef.current)) { return false; } return !!containerRef.current.contains(event.relatedTarget as Node); -} +}; export default isCurrentTargetInsideContainer; diff --git a/src/components/AddressSearch/types.ts b/src/components/AddressSearch/types.ts index b52b816722df..1ae42eb11e35 100644 --- a/src/components/AddressSearch/types.ts +++ b/src/components/AddressSearch/types.ts @@ -1,4 +1,5 @@ -import type {StyleProp, ViewStyle} from 'react-native'; +import type {RefObject} from 'react'; +import type {NativeSyntheticEvent, StyleProp, TextInputFocusEventData, View, ViewStyle} from 'react-native'; import type {Place} from 'react-native-google-places-autocomplete'; import type Locale from '@src/types/onyx/Locale'; @@ -90,4 +91,6 @@ type AddressSearchProps = { preferredLocale?: Locale; }; -export type {CurrentLocationButtonProps, AddressSearchProps, RenamedInputKeysProps}; +type IsCurrentTargetInsideContainerType = (event: FocusEvent | NativeSyntheticEvent, containerRef: RefObject) => boolean; + +export type {CurrentLocationButtonProps, AddressSearchProps, RenamedInputKeysProps, IsCurrentTargetInsideContainerType}; diff --git a/src/components/LocationErrorMessage/BaseLocationErrorMessage.tsx b/src/components/LocationErrorMessage/BaseLocationErrorMessage.tsx index 33a0bba7481c..54f8049c6fb7 100644 --- a/src/components/LocationErrorMessage/BaseLocationErrorMessage.tsx +++ b/src/components/LocationErrorMessage/BaseLocationErrorMessage.tsx @@ -12,7 +12,7 @@ import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import colors from '@styles/theme/colors'; import CONST from '@src/CONST'; -import type LocationErrorMessageProps from './types'; +import type {LocationErrorMessageProps} from './types'; type BaseLocationErrorMessageProps = LocationErrorMessageProps & { /** A callback that runs when 'allow location permission' link is pressed */ diff --git a/src/components/LocationErrorMessage/index.native.tsx b/src/components/LocationErrorMessage/index.native.tsx index 7936fff73c06..b2cca9e44237 100644 --- a/src/components/LocationErrorMessage/index.native.tsx +++ b/src/components/LocationErrorMessage/index.native.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {Linking} from 'react-native'; import BaseLocationErrorMessage from './BaseLocationErrorMessage'; -import type LocationErrorMessageProps from './types'; +import type {LocationErrorMessageProps} from './types'; /** Opens app level settings from the native system settings */ const openAppSettings = () => { diff --git a/src/components/LocationErrorMessage/index.tsx b/src/components/LocationErrorMessage/index.tsx index 193d38069d65..850cdf3a45e6 100644 --- a/src/components/LocationErrorMessage/index.tsx +++ b/src/components/LocationErrorMessage/index.tsx @@ -2,7 +2,7 @@ import React from 'react'; import {Linking} from 'react-native'; import CONST from '@src/CONST'; import BaseLocationErrorMessage from './BaseLocationErrorMessage'; -import type LocationErrorMessageProps from './types'; +import type {LocationErrorMessageProps} from './types'; /** Opens expensify help site in a new browser tab */ const navigateToExpensifyHelpSite = () => { diff --git a/src/components/LocationErrorMessage/types.ts b/src/components/LocationErrorMessage/types.ts index 78b8d32d770d..0b7ee4ceaf9c 100644 --- a/src/components/LocationErrorMessage/types.ts +++ b/src/components/LocationErrorMessage/types.ts @@ -1,3 +1,5 @@ +type LocationErrorCodeType = -1 | 1 | 2 | 3 | null; + type LocationErrorMessageProps = { /** A callback that runs when close icon is pressed */ onClose: () => void; @@ -9,7 +11,7 @@ type LocationErrorMessageProps = { * - code 2 = location is unavailable or there is some connection issue * - code 3 = location fetch timeout */ - locationErrorCode?: number | null; + locationErrorCode?: LocationErrorCodeType; }; -export default LocationErrorMessageProps; +export type {LocationErrorMessageProps, LocationErrorCodeType};