From 9d4737f553bf282c856291f5a8a276ff808b1f3f Mon Sep 17 00:00:00 2001 From: Ole Date: Tue, 28 Jan 2025 16:46:42 +0100 Subject: [PATCH] fix: Filter out disliked artworks correctly on the home screen for all recommendation rails (#11366) * fix: Filter out disliked artworks on artworks rail * more rails & refetch * rename * do not render section when no artworks * feature flag * import * remove early return * fix tests --- .../ContextMenu/ContextMenuArtwork.tsx | 31 ++-------------- .../Sections/HomeViewSectionActivity.tsx | 15 +++++--- .../Sections/HomeViewSectionArtworks.tsx | 36 ++++++++++++++----- .../HomeViewSectionArtworks.tests.tsx | 31 +++++++++++++++- src/app/store/config/features.ts | 8 ++++- src/app/utils/isDislikeArtworksEnabledFor.ts | 15 ++++++++ 6 files changed, 94 insertions(+), 42 deletions(-) create mode 100644 src/app/utils/isDislikeArtworksEnabledFor.ts diff --git a/src/app/Components/ContextMenu/ContextMenuArtwork.tsx b/src/app/Components/ContextMenu/ContextMenuArtwork.tsx index e3219a896c3..1a6e8af1674 100644 --- a/src/app/Components/ContextMenu/ContextMenuArtwork.tsx +++ b/src/app/Components/ContextMenu/ContextMenuArtwork.tsx @@ -2,7 +2,6 @@ import { ActionType, ContextModule, LongPressedArtwork, ScreenOwnerType } from " import { Box, Flex, Join, Separator, Text, Touchable, useColor } from "@artsy/palette-mobile" import { ContextMenuArtworkPreviewCard_artwork$key } from "__generated__/ContextMenuArtworkPreviewCard_artwork.graphql" import { ContextMenuArtwork_artwork$key } from "__generated__/ContextMenuArtwork_artwork.graphql" -import { useSaveArtworkToArtworkLists } from "app/Components/ArtworkLists/useSaveArtworkToArtworkLists" import { ArtworkRailCardProps } from "app/Components/ArtworkRail/ArtworkRailCard" import { AutoHeightBottomSheet } from "app/Components/BottomSheet/AutoHeightBottomSheet" import { ContextMenuArtworkPreviewCard } from "app/Components/ContextMenu/ContextMenuArtworkPreviewCard" @@ -10,9 +9,9 @@ import { useShareSheet } from "app/Components/ShareSheet/ShareSheetContext" import { LegacyNativeModules } from "app/NativeModules/LegacyNativeModules" import { cm2in } from "app/utils/conversions" import { useFeatureFlag } from "app/utils/hooks/useFeatureFlag" +import { isDislikeArtworksEnabledFor } from "app/utils/isDislikeArtworksEnabledFor" import { useDislikeArtwork } from "app/utils/mutations/useDislikeArtwork" import { Schema } from "app/utils/track" -import { isEmpty } from "lodash" import { useState } from "react" import { InteractionManager, Platform, SafeAreaView } from "react-native" import ContextMenu, { ContextMenuAction, ContextMenuProps } from "react-native-context-menu-view" @@ -64,20 +63,11 @@ export const ContextMenuArtwork: React.FC = ({ const dark = artworkDisplayProps?.dark ?? false - const { title, href, artists, slug, internalID, id, isHangable, image, sale } = artwork + const { title, href, artists, slug, internalID, id, isHangable, image } = artwork const enableCreateAlerts = !!artwork.artists?.length const enableViewInRoom = LegacyNativeModules.ARCocoaConstantsModule.AREnabled && isHangable - const enableSupressArtwork = contextModule == "newWorksForYouRail" - - const isOpenSale = !isEmpty(sale) && sale?.isAuction && !sale?.isClosed - - const { isSaved, saveArtworkToLists } = useSaveArtworkToArtworkLists({ - artworkFragmentRef: artwork, - onCompleted: - // TODO: Do we need to track anything here? - () => null, - }) + const enableSupressArtwork = isDislikeArtworksEnabledFor(contextModule) const openViewInRoom = () => { if (artwork?.widthCm == null || artwork?.heightCm == null || image?.url == null) { @@ -125,21 +115,6 @@ export const ContextMenuArtwork: React.FC = ({ }, ] - if (!enableSupressArtwork) { - let saveTitle = isSaved ? "Remove from saved" : "Save" - if (isOpenSale) { - saveTitle = "Watch Lot" - } - - contextMenuActions.unshift({ - title: saveTitle, - systemIcon: isSaved ? "heart.fill" : "heart", - onPress: () => { - saveArtworkToLists() - }, - }) - } - if (enableViewInRoom) { contextMenuActions.push({ title: "View in room", diff --git a/src/app/Scenes/HomeView/Sections/HomeViewSectionActivity.tsx b/src/app/Scenes/HomeView/Sections/HomeViewSectionActivity.tsx index 4cf99e9e0dc..d1496ffdcb4 100644 --- a/src/app/Scenes/HomeView/Sections/HomeViewSectionActivity.tsx +++ b/src/app/Scenes/HomeView/Sections/HomeViewSectionActivity.tsx @@ -195,10 +195,17 @@ const HomeViewSectionActivityPlaceholder: React.FC = (flexProps) => { export const HomeViewSectionActivityQueryRenderer: React.FC = memo( withSuspense({ - Component: ({ sectionID, index, ...flexProps }) => { - const data = useLazyLoadQuery(homeViewSectionActivityQuery, { - id: sectionID, - }) + Component: ({ sectionID, index, refetchKey, ...flexProps }) => { + const data = useLazyLoadQuery( + homeViewSectionActivityQuery, + { + id: sectionID, + }, + { + fetchKey: refetchKey, + fetchPolicy: "store-and-network", + } + ) if (!data.homeView.section) { return null diff --git a/src/app/Scenes/HomeView/Sections/HomeViewSectionArtworks.tsx b/src/app/Scenes/HomeView/Sections/HomeViewSectionArtworks.tsx index 536ef2ea3ff..ab202571cae 100644 --- a/src/app/Scenes/HomeView/Sections/HomeViewSectionArtworks.tsx +++ b/src/app/Scenes/HomeView/Sections/HomeViewSectionArtworks.tsx @@ -23,7 +23,9 @@ import { getHomeViewSectionHref } from "app/Scenes/HomeView/helpers/getHomeViewS import { useHomeViewTracking } from "app/Scenes/HomeView/hooks/useHomeViewTracking" import { navigate } from "app/system/navigation/navigate" import { extractNodes } from "app/utils/extractNodes" +import { useFeatureFlag } from "app/utils/hooks/useFeatureFlag" import { NoFallback, withSuspense } from "app/utils/hooks/withSuspense" +import { isDislikeArtworksEnabledFor } from "app/utils/isDislikeArtworksEnabledFor" import { useMemoizedRandom } from "app/utils/placeholders" import { times } from "lodash" import { memo } from "react" @@ -42,10 +44,15 @@ export const HomeViewSectionArtworks: React.FC = ( const tracking = useHomeViewTracking() const section = useFragment(fragment, sectionProp) - const artworks = extractNodes(section.artworksConnection) + let artworks = extractNodes(section.artworksConnection) + + if (isDislikeArtworksEnabledFor(section.contextModule)) { + artworks = artworks.filter((artwork) => !artwork.isDisliked) + } + const viewAll = section.component?.behaviors?.viewAll - if (!artworks || artworks.length === 0) { + if (!artworks.length) { return null } @@ -107,7 +114,8 @@ export const HomeViewSectionArtworks: React.FC = ( } const fragment = graphql` - fragment HomeViewSectionArtworks_section on HomeViewSectionArtworks { + fragment HomeViewSectionArtworks_section on HomeViewSectionArtworks + @argumentDefinitions(enableHidingDislikedArtworks: { type: "Boolean", defaultValue: false }) { __typename internalID contextModule @@ -125,6 +133,7 @@ const fragment = graphql` artworksConnection(first: 10) { edges { node { + isDisliked @include(if: $enableHidingDislikedArtworks) ...ArtworkRail_artworks } } @@ -133,10 +142,11 @@ const fragment = graphql` ` const homeViewSectionArtworksQuery = graphql` - query HomeViewSectionArtworksQuery($id: String!) { + query HomeViewSectionArtworksQuery($id: String!, $enableHidingDislikedArtworks: Boolean!) { homeView { section(id: $id) { ...HomeViewSectionArtworks_section + @arguments(enableHidingDislikedArtworks: $enableHidingDislikedArtworks) } } } @@ -181,10 +191,20 @@ const HomeViewSectionArtworksPlaceholder: React.FC = (flexProps) => { export const HomeViewSectionArtworksQueryRenderer: React.FC = memo( withSuspense({ - Component: ({ sectionID, index, ...flexProps }) => { - const data = useLazyLoadQuery(homeViewSectionArtworksQuery, { - id: sectionID, - }) + Component: ({ sectionID, index, refetchKey, ...flexProps }) => { + const enableHidingDislikedArtworks = useFeatureFlag("AREnableHidingDislikedArtworks") + + const data = useLazyLoadQuery( + homeViewSectionArtworksQuery, + { + id: sectionID, + enableHidingDislikedArtworks, + }, + { + fetchKey: refetchKey, + fetchPolicy: "store-and-network", + } + ) if (!data.homeView.section) { return null diff --git a/src/app/Scenes/HomeView/Sections/__tests__/HomeViewSectionArtworks.tests.tsx b/src/app/Scenes/HomeView/Sections/__tests__/HomeViewSectionArtworks.tests.tsx index 2d5b680d1eb..70842de6795 100644 --- a/src/app/Scenes/HomeView/Sections/__tests__/HomeViewSectionArtworks.tests.tsx +++ b/src/app/Scenes/HomeView/Sections/__tests__/HomeViewSectionArtworks.tests.tsx @@ -2,12 +2,17 @@ import { fireEvent, screen } from "@testing-library/react-native" import { HomeViewSectionArtworksTestsQuery } from "__generated__/HomeViewSectionArtworksTestsQuery.graphql" import { HomeViewStoreProvider } from "app/Scenes/HomeView/HomeViewContext" import { HomeViewSectionArtworks } from "app/Scenes/HomeView/Sections/HomeViewSectionArtworks" +import { __globalStoreTestUtils__ } from "app/store/GlobalStore" import { navigate } from "app/system/navigation/navigate" import { mockTrackEvent } from "app/utils/tests/globallyMockedStuff" import { setupTestWrapper } from "app/utils/tests/setupTestWrapper" import { graphql } from "react-relay" describe("HomeViewSectionArtworks", () => { + beforeEach(() => { + __globalStoreTestUtils__?.injectFeatureFlags({ AREnableHidingDislikedArtworks: true }) + }) + const { renderWithRelay } = setupTestWrapper({ Component: (props) => { if (!props.homeView.section) { @@ -24,7 +29,7 @@ describe("HomeViewSectionArtworks", () => { homeView { section(id: "home-view-section-new-works-for-you") { ... on HomeViewSectionArtworks { - ...HomeViewSectionArtworks_section + ...HomeViewSectionArtworks_section @arguments(enableHidingDislikedArtworks: true) } } } @@ -102,4 +107,28 @@ describe("HomeViewSectionArtworks", () => { expect(navigate).toHaveBeenCalledWith("/artwork-2-href") }) + + it("does not render disliked artworks when enabled", () => { + renderWithRelay({ + HomeViewSectionArtworks: () => ({ + internalID: "home-view-section-new-works-for-you", + contextModule: "newWorksForYouRail", + artworksConnection: { + edges: [ + { + node: { + internalID: "artwork-1-id", + slug: "artwork-1-slug", + title: "Artwork 1", + href: "/artwork-1-href", + isDisliked: true, + }, + }, + ], + }, + }), + }) + + expect(screen.queryByText(/Artwork 1/)).not.toBeOnTheScreen() + }) }) diff --git a/src/app/store/config/features.ts b/src/app/store/config/features.ts index dfeddb87192..a9afd447283 100644 --- a/src/app/store/config/features.ts +++ b/src/app/store/config/features.ts @@ -257,11 +257,17 @@ export const features = { readyForRelease: false, showInDevMenu: true, }, + AREnableHidingDislikedArtworks: { + description: "Enable hiding disliked artworks", + readyForRelease: true, + showInDevMenu: true, + echoFlagKey: "AREnableHidingDislikedArtworks", + }, AREnableArtworkCardContextMenuAndroid: { description: "Enable long press menu on artwork cards for Android", readyForRelease: false, showInDevMenu: true, - // echoFlagKey: "AREnableArtworkCardContextMenuAndroid", + echoFlagKey: "AREnableArtworkCardContextMenuAndroid", }, } satisfies { [key: string]: FeatureDescriptor } diff --git a/src/app/utils/isDislikeArtworksEnabledFor.ts b/src/app/utils/isDislikeArtworksEnabledFor.ts new file mode 100644 index 00000000000..722dd5ccf93 --- /dev/null +++ b/src/app/utils/isDislikeArtworksEnabledFor.ts @@ -0,0 +1,15 @@ +import { ContextModule } from "@artsy/cohesion" + +const ENABLED_CONTEXT_MODULES = [ + ContextModule.newWorksForYouRail, + ContextModule.artworkRecommendationsRail, + ContextModule.lotsForYouRail, + ContextModule.newWorksByGalleriesYouFollowRail, +] + +/** + * returns true if hiding disliked artworks is enabled for the given context module + */ +export const isDislikeArtworksEnabledFor = (contextModule: string | null | undefined) => { + return ENABLED_CONTEXT_MODULES.includes(contextModule as ContextModule) +}