Skip to content

Commit

Permalink
feat: support navigating to artist artworks grid - mounir (#9403)
Browse files Browse the repository at this point in the history
* feat: support navigating to artworks grid

* feat: navigate to artist artworks on activity items press

* chore: remove non-needed-padding

* chore: update palette

* chore: define artist/artworks route

* fix: broken test

* chore: address review comment

* chore: adjust AutosuggestSearchResult logic
  • Loading branch information
MounirDhahri authored Oct 12, 2023
1 parent 2db5abe commit cd3c86f
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 22 deletions.
16 changes: 15 additions & 1 deletion src/app/Components/Artist/ArtistArtworks/ArtistArtworks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
useScreenDimensions,
useSpace,
} from "@artsy/palette-mobile"
import { MasonryFlashListRef } from "@shopify/flash-list"
import { ArtistArtworks_artist$data } from "__generated__/ArtistArtworks_artist.graphql"
import { ArtistArtworksFilterHeader } from "app/Components/Artist/ArtistArtworks/ArtistArtworksFilterHeader"
import { CreateSavedSearchModal } from "app/Components/Artist/ArtistArtworks/CreateSavedSearchModal"
Expand All @@ -36,7 +37,7 @@ import {
ON_END_REACHED_THRESHOLD_MASONRY,
} from "app/utils/masonryHelpers"
import { Schema } from "app/utils/track"
import React, { useCallback, useEffect, useMemo, useState } from "react"
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"
import { RelayPaginationProp, createPaginationContainer, graphql } from "react-relay"
import { useTracking } from "react-tracking"

Expand All @@ -45,12 +46,14 @@ interface ArtworksGridProps extends InfiniteScrollGridProps {
searchCriteria: SearchCriteriaAttributes | null
relay: RelayPaginationProp
predefinedFilters?: FilterArray
scrollToArtworksGrid: boolean
}

const ArtworksGrid: React.FC<ArtworksGridProps> = ({
artist,
relay,
predefinedFilters,
scrollToArtworksGrid,
searchCriteria,
...props
}) => {
Expand All @@ -64,6 +67,9 @@ const ArtworksGrid: React.FC<ArtworksGridProps> = ({
const showCreateAlertAtEndOfList = useFeatureFlag("ARShowCreateAlertInArtistArtworksListFooter")
const enableAlertsFilters = useFeatureFlag("AREnableAlertsFilters")
const artworks = useMemo(() => extractNodes(artist.artworks), [artist.artworks])

const gridRef = useRef<MasonryFlashListRef<typeof artworks[0]>>(null)

const appliedFilters = ArtworksFiltersStore.useStoreState((state) => state.appliedFilters)

const { navigateToPageableRoute } = useNavigateToPageableRoute({ items: artworks })
Expand Down Expand Up @@ -100,6 +106,13 @@ const ArtworksGrid: React.FC<ArtworksGridProps> = ({
setInitialFilterStateAction(filters)
}, [])

useEffect(() => {
if (scrollToArtworksGrid) {
setTimeout(() => {
gridRef.current?.scrollToOffset({ offset: 0, animated: true })
}, 1000)
}
})
const { savedSearchEntity, attributes } = useCreateSavedSearchModalFilters({
entityId: artist.internalID!,
entityName: artist.name ?? "",
Expand Down Expand Up @@ -232,6 +245,7 @@ const ArtworksGrid: React.FC<ArtworksGridProps> = ({
numColumns={NUM_COLUMNS_MASONRY}
estimatedItemSize={ESTIMATED_MASONRY_ITEM_SIZE}
keyboardShouldPersistTaps="handled"
innerRef={gridRef}
ListEmptyComponent={
<Box mb="80px" pt={2}>
<FilteredArtworkGridZeroState
Expand Down
3 changes: 3 additions & 0 deletions src/app/Scenes/Activity/ActivityItem.tests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ describe("ActivityItem", () => {
paramValue: "-published_at",
},
],
scrollToArtworksGrid: true,
searchCriteriaID: undefined,
},
})
})
Expand All @@ -137,6 +139,7 @@ describe("ActivityItem", () => {

expect(navigate).toHaveBeenCalledWith(alertTargetUrl, {
passProps: {
scrollToArtworksGrid: true,
searchCriteriaID: "searchCriteriaId",
predefinedFilters: [
{
Expand Down
15 changes: 11 additions & 4 deletions src/app/Scenes/Activity/utils/navigateToActivityItem.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { FilterArray } from "app/Components/ArtworkFilter/ArtworkFilterHelpers"
import { ORDERED_ARTWORK_SORTS } from "app/Components/ArtworkFilter/Filters/SortOptions"
import { matchRoute } from "app/routes"
import { navigate } from "app/system/navigation/navigate"
import { last } from "lodash"
import { parse as parseQueryString } from "query-string"
Expand All @@ -13,10 +14,16 @@ export const navigateToActivityItem = (targetHref: string) => {
(sortEntity) => sortEntity.paramValue === "-published_at"
)!

const passProps: any = {
predefinedFilters: [sortFilterItem] as FilterArray,
searchCriteriaID: parsed.search_criteria_id,
}

if ((matchRoute(targetHref) as any).module === "Artist") {
passProps.scrollToArtworksGrid = true
}

navigate(targetHref, {
passProps: {
predefinedFilters: [sortFilterItem] as FilterArray,
searchCriteriaID: parsed.search_criteria_id,
},
passProps,
})
}
20 changes: 13 additions & 7 deletions src/app/Scenes/Artist/Artist.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ interface ArtistProps {
initialTab?: string
me: ArtistAboveTheFoldQuery["response"]["me"]
predefinedFilters?: FilterArray
scrollToArtworksGrid: boolean
searchCriteria: SearchCriteriaAttributes | null
}

Expand All @@ -69,6 +70,7 @@ export const Artist: React.FC<ArtistProps> = (props) => {
initialTab = INITIAL_TAB,
me,
predefinedFilters,
scrollToArtworksGrid,
searchCriteria,
} = props

Expand Down Expand Up @@ -142,6 +144,7 @@ export const Artist: React.FC<ArtistProps> = (props) => {
artist={artistAboveTheFold}
searchCriteria={searchCriteria}
predefinedFilters={predefinedFilters}
scrollToArtworksGrid={scrollToArtworksGrid}
/>
</Tabs.Lazy>
</Tabs.Tab>
Expand Down Expand Up @@ -175,13 +178,14 @@ export const Artist: React.FC<ArtistProps> = (props) => {
}

interface ArtistQueryRendererProps {
artistID: string
categories?: string[]
environment?: RelayModernEnvironment
initialTab?: string
searchCriteriaID?: string
search_criteria_id?: string
artistID: string
predefinedFilters?: FilterArray
categories?: string[]
scrollToArtworksGrid?: boolean
search_criteria_id?: string
searchCriteriaID?: string
sizes?: string[]
}

Expand Down Expand Up @@ -215,12 +219,13 @@ export const defaultArtistVariables = () => ({
export const ArtistQueryRenderer: React.FC<ArtistQueryRendererProps> = (props) => {
const {
artistID,
categories,
environment,
initialTab,
searchCriteriaID,
search_criteria_id,
predefinedFilters,
categories,
search_criteria_id,
scrollToArtworksGrid = false,
searchCriteriaID,
sizes,
} = props

Expand Down Expand Up @@ -290,6 +295,7 @@ export const ArtistQueryRenderer: React.FC<ArtistQueryRendererProps> = (props) =
categories: categories ?? [],
sizes: sizes ?? [],
})}
scrollToArtworksGrid={scrollToArtworksGrid}
/>
)
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Touchable } from "@artsy/palette-mobile"
import { fireEvent } from "@testing-library/react-native"
import { SearchContext } from "app/Scenes/Search/SearchContext"
import { GlobalStore, GlobalStoreProvider } from "app/store/GlobalStore"
import { EntityType, navigate, navigateToEntity, SlugType } from "app/system/navigation/navigate"
import { CatchErrors } from "app/utils/CatchErrors"
import { extractText } from "app/utils/tests/extractText"
import { renderWithWrappers, renderWithWrappersLEGACY } from "app/utils/tests/renderWithWrappers"
import { Touchable } from "@artsy/palette-mobile"
import { Pressable } from "react-native"
import { act } from "react-test-renderer"
import { AutosuggestSearchResult } from "./AutosuggestSearchResult"
Expand Down Expand Up @@ -92,7 +92,7 @@ describe(AutosuggestSearchResult, () => {
tree.root.findByType(Touchable).props.onPress()
await new Promise((r) => setTimeout(r, 50))
expect(inputBlurMock).toHaveBeenCalled()
expect(navigate).toHaveBeenCalledWith(result.href, { passProps: { initialTab: "Artworks" } })
expect(navigate).toHaveBeenCalledWith(`${result.href}`)
})

it(`highlights a part of the string even when the string has diacritics but the highlight doesn't`, async () => {
Expand Down Expand Up @@ -253,15 +253,15 @@ describe(AutosuggestSearchResult, () => {
tree.root.findAllByType(Pressable)[0].props.onPress()
})
await new Promise((r) => setTimeout(r, 50))
expect(navigate).toHaveBeenCalledWith("/artist/anto-carte", {
expect(navigate).toHaveBeenCalledWith("/artist/anto-carte/artworks", {
passProps: { initialTab: "Artworks" },
})

act(() => {
tree.root.findAllByType(Pressable)[1].props.onPress()
})
await new Promise((r) => setTimeout(r, 50))
expect(navigate).toHaveBeenCalledWith("/artist/anto-carte", {
expect(navigate).toHaveBeenCalledWith("/artist/anto-carte/auction-results", {
passProps: { initialTab: "Insights" },
})
})
Expand Down
22 changes: 16 additions & 6 deletions src/app/Scenes/Search/components/AutosuggestSearchResult.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ export type TrackResultPress = (result: AutosuggestResult, itemIndex?: number) =

type ArtistTabs = "Insights" | "Artworks"

type HandleResultPress = (passProps?: { artistTab: ArtistTabs }) => void
type PassedProps = {
initialTab: ArtistTabs
}

type HandleResultPress = (passProps?: PassedProps) => void

const getResultType = (result: AutosuggestResult) => {
if (result.displayType) {
Expand Down Expand Up @@ -77,7 +81,7 @@ export const AutosuggestSearchResult: React.FC<{
inputRef.current?.blur()
// need to wait a tick to push next view otherwise the input won't blur ¯\_(ツ)_/¯
setTimeout(() => {
navigateToResult(result, passProps?.artistTab)
navigateToResult(result, passProps)
if (updateRecentSearchesOnTap) {
GlobalStore.actions.search.addRecentSearch({
type: "AUTOSUGGEST_RESULT_TAPPED",
Expand Down Expand Up @@ -162,7 +166,7 @@ export const AutosuggestSearchResult: React.FC<{
highlightEnabled
Icon={ArtworkIcon}
rounded
onPress={() => onPress({ artistTab: "Artworks" })}
onPress={() => onPress({ initialTab: "Artworks" })}
block
>
Artworks
Expand All @@ -172,7 +176,7 @@ export const AutosuggestSearchResult: React.FC<{
highlightEnabled
Icon={AuctionIcon}
rounded
onPress={() => onPress({ artistTab: "Insights" })}
onPress={() => onPress({ initialTab: "Insights" })}
block
>
Auction Results
Expand All @@ -189,13 +193,19 @@ export const AutosuggestSearchResult: React.FC<{
* about the entity type to render the correct placeholder/skeleton loader
* @param result
*/
function navigateToResult(result: AutosuggestResult, artistTab: ArtistTabs = "Artworks") {
function navigateToResult(result: AutosuggestResult, props?: PassedProps) {
if (result.displayType === "Gallery" || result.displayType === "Institution") {
navigateToPartner(result.href!)
} else if (result.displayType === "Fair") {
navigateToEntity(result.href!, EntityType.Fair, SlugType.ProfileID)
} else if (result.__typename === "Artist") {
navigate(result.href!, { passProps: { initialTab: artistTab } })
if (props?.initialTab === "Insights") {
navigate(`${result.href!}/auction-results`, { passProps: props })
}
if (props?.initialTab === "Artworks") {
navigate(`${result.href!}/artworks`, { passProps: props })
}
navigate(result.href!)
} else {
navigate(result.href!)
}
Expand Down
4 changes: 4 additions & 0 deletions src/app/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ function getDomainMap(): Record<string, RouteMatcher[] | null> {
...params,
initialTab: "Insights",
})),
addRoute("/artist/:artistID/artworks", "Artist", (params) => ({
...params,
initialTab: "Insights",
})),
addRoute("/artist/:artistID/shows", "ArtistShows"),

// Routes `/artist/:artistID/*` and `"/:profile_id_ignored/artist/:artistID"`
Expand Down

0 comments on commit cd3c86f

Please sign in to comment.