Skip to content

Commit

Permalink
chore: search overlay on tab press (#11165)
Browse files Browse the repository at this point in the history
chore: dimsis overlay on tab press
  • Loading branch information
MounirDhahri authored Nov 21, 2024
1 parent 7549399 commit d914193
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 21 deletions.
11 changes: 8 additions & 3 deletions src/app/Components/GlobalSearchInput/GlobalSearchInput.tests.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { OwnerType } from "@artsy/cohesion"
import { fireEvent, screen } from "@testing-library/react-native"
import { GlobalSearchInput } from "app/Components/GlobalSearchInput/GlobalSearchInput"
import { useSelectedTab } from "app/utils/hooks/useSelectedTab"
Expand All @@ -8,6 +9,10 @@ jest.mock("app/utils/hooks/useSelectedTab", () => ({
useSelectedTab: jest.fn(),
}))

jest.mock("app/Components/GlobalSearchInput/utils/useDismissSearchOverlayOnTabBarPress", () => ({
useDismissSearchOverlayOnTabBarPress: jest.fn(),
}))

describe("GlobalSearchInput", () => {
const mockUseledTab = useSelectedTab as jest.Mock

Expand All @@ -16,20 +21,20 @@ describe("GlobalSearchInput", () => {
})

it("renders the search label properly", () => {
renderWithWrappers(<GlobalSearchInput />)
renderWithWrappers(<GlobalSearchInput ownerType={OwnerType.home} />)

expect(/Search Artsy/).toBeTruthy()
})

it("tracks the search bar tapped event", () => {
renderWithWrappers(<GlobalSearchInput />)
renderWithWrappers(<GlobalSearchInput ownerType={OwnerType.home} />)

fireEvent.press(screen.getByTestId("search-button"))

expect(mockTrackEvent).toHaveBeenCalledWith(
expect.objectContaining({
action: "tappedGlobalSearchBar",
context_module: "home",
context_screen_owner_type: "home",
})
)
})
Expand Down
23 changes: 15 additions & 8 deletions src/app/Components/GlobalSearchInput/GlobalSearchInput.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
import { ActionType, ContextModule } from "@artsy/cohesion"
import { ActionType, OwnerType } from "@artsy/cohesion"
import { Flex, RoundSearchInput, Touchable } from "@artsy/palette-mobile"
import { GlobalSearchInputOverlay } from "app/Components/GlobalSearchInput/GlobalSearchInputOverlay"
import { useDismissSearchOverlayOnTabBarPress } from "app/Components/GlobalSearchInput/utils/useDismissSearchOverlayOnTabBarPress"
import { ICON_HIT_SLOP } from "app/Components/constants"
import { useSelectedTab } from "app/utils/hooks/useSelectedTab"
import { Fragment, useState } from "react"
import { useTracking } from "react-tracking"

export const GlobalSearchInput: React.FC<{}> = () => {
export const GlobalSearchInput: React.FC<{
ownerType: OwnerType
}> = ({ ownerType }) => {
const [isVisible, setIsVisible] = useState(false)
const tracking = useTracking()
const selectedTab = useSelectedTab()

useDismissSearchOverlayOnTabBarPress({ isVisible, ownerType, setIsVisible })

return (
<Fragment>
<Touchable
onPress={() => {
tracking.trackEvent(
tracks.tappedGlobalSearchBar({
contextModule: selectedTab as ContextModule,
ownerType,
})
)
setIsVisible(true)
Expand All @@ -40,14 +43,18 @@ export const GlobalSearchInput: React.FC<{}> = () => {
/>
</Flex>
</Touchable>
<GlobalSearchInputOverlay visible={isVisible} hideModal={() => setIsVisible(false)} />
<GlobalSearchInputOverlay
ownerType={ownerType}
visible={isVisible}
hideModal={() => setIsVisible(false)}
/>
</Fragment>
)
}

const tracks = {
tappedGlobalSearchBar: ({ contextModule }: { contextModule: ContextModule }) => ({
tappedGlobalSearchBar: ({ ownerType }: { ownerType: OwnerType }) => ({
action: ActionType.tappedGlobalSearchBar,
context_module: contextModule,
context_screen_owner_type: ownerType,
}),
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { OwnerType } from "@artsy/cohesion"
import { Box, Flex, RoundSearchInput, Spacer, Spinner, useSpace } from "@artsy/palette-mobile"
import { Portal } from "@gorhom/portal"
import { FadeIn } from "app/Components/FadeIn"
Expand Down Expand Up @@ -78,10 +79,11 @@ const GlobalSearchInputOverlayContent: React.FC<{ query: string }> = ({ query })
)
}

export const GlobalSearchInputOverlay: React.FC<{ visible: boolean; hideModal: () => void }> = ({
visible,
hideModal,
}) => {
export const GlobalSearchInputOverlay: React.FC<{
ownerType: OwnerType
visible: boolean
hideModal: () => void
}> = ({ hideModal, ownerType, visible }) => {
const [query, setQuery] = useState("")
const insets = useSafeAreaInsets()

Expand All @@ -104,7 +106,7 @@ export const GlobalSearchInputOverlay: React.FC<{ visible: boolean; hideModal: (

return (
<FadeIn style={{ flex: 1 }} slide={false}>
<Portal hostName="SearchOverlay">
<Portal hostName={`${ownerType}-SearchOverlay`}>
<Flex style={{ ...StyleSheet.absoluteFillObject }}>
<Flex flex={1} backgroundColor="white100" style={{ ...insets }}>
<Flex px={2} pt={2}>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useIsFocused, useNavigation } from "@react-navigation/native"
import { GlobalStore } from "app/store/GlobalStore"
import { useEffect } from "react"

/**
* Dismisses the GlobalSearchInputOverlay when the tab bar is pressed
*/
export const useDismissSearchOverlayOnTabBarPress = ({
isVisible,
ownerType,
setIsVisible,
}: {
isVisible: boolean
ownerType: string
setIsVisible: React.Dispatch<React.SetStateAction<boolean>>
}) => {
const isFocused = useIsFocused()
const selectedTab = GlobalStore.useAppState((state) => state.bottomTabs.sessionState.selectedTab)

const navigation = useNavigation()

useEffect(() => {
const tabsNavigation = navigation?.getParent()
const unsubscribe = tabsNavigation?.addListener("tabPress" as any, () => {
if (!isFocused || !isVisible) {
return
}

if (ownerType === selectedTab.toLowerCase()) {
setIsVisible(false)
}
})
return unsubscribe
}, [isVisible, selectedTab, navigation, isFocused])
}
3 changes: 2 additions & 1 deletion src/app/Navigation/AuthenticatedRoutes/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { BottomTabsButton } from "app/Scenes/BottomTabs/BottomTabsButton"
import { bottomTabsConfig } from "app/Scenes/BottomTabs/bottomTabsConfig"
import { OnboardingQuiz } from "app/Scenes/Onboarding/OnboardingQuiz/OnboardingQuiz"
import { GlobalStore } from "app/store/GlobalStore"
import { internal_navigationRef } from "app/system/navigation/navigate"
import { internal_navigationRef, switchTab } from "app/system/navigation/navigate"
import { postEventToProviders } from "app/utils/track/providers"
import { Platform } from "react-native"

Expand Down Expand Up @@ -66,6 +66,7 @@ const AppTabs: React.FC = () => {
const tabName = Object.keys(bottomTabsConfig).find((tab) => e.target?.startsWith(tab))

if (tabName) {
switchTab(tabName as BottomTabType)
postEventToProviders(
tappedTabBar({
tab: bottomTabsConfig[tabName as BottomTabType].analyticsDescription,
Expand Down
3 changes: 2 additions & 1 deletion src/app/Scenes/HomeView/Components/HomeHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { OwnerType } from "@artsy/cohesion"
import { ArtsyLogoBlackIcon, Box, Flex } from "@artsy/palette-mobile"
import { GlobalSearchInput } from "app/Components/GlobalSearchInput/GlobalSearchInput"
import { PaymentFailureBanner } from "app/Scenes/HomeView/Components/PaymentFailureBanner"
Expand Down Expand Up @@ -30,7 +31,7 @@ export const HomeHeader: React.FC = () => {
alignItems="center"
>
<Flex flex={1}>
<GlobalSearchInput />
<GlobalSearchInput ownerType={OwnerType.home} />
</Flex>
<Flex alignItems="flex-end">
<ActivityIndicator hasUnseenNotifications={hasUnseenNotifications} />
Expand Down
2 changes: 1 addition & 1 deletion src/app/Scenes/HomeView/HomeView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ export const HomeViewScreen: React.FC = () => {
<Suspense fallback={<HomeViewScreenPlaceholder />}>
<HomeView />
</Suspense>
<PortalHost name="SearchOverlay" />
<PortalHost name={`${OwnerType.home}-SearchOverlay`} />
</RetryErrorBoundary>
</HomeViewStoreProvider>
)
Expand Down
4 changes: 2 additions & 2 deletions src/app/Scenes/Search/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export const Search: React.FC = () => {
<ArtsyKeyboardAvoidingView>
<Flex p={2} pb={0}>
{enableNewSearchModal ? (
<GlobalSearchInput />
<GlobalSearchInput ownerType={OwnerType.search} />
) : (
<SearchInput
ref={searchProviderValues?.inputRef}
Expand Down Expand Up @@ -209,7 +209,7 @@ export const SearchScreen: React.FC<SearchScreenProps> = () => {
<Search />
</Suspense>
</Screen>
<PortalHost name="SearchOverlay" />
<PortalHost name={`${OwnerType.search}-SearchOverlay`} />
</>
)
}
Expand Down

0 comments on commit d914193

Please sign in to comment.