diff --git a/src/app/Components/ArtworkGrids/GenericGrid.tsx b/src/app/Components/ArtworkGrids/GenericGrid.tsx index b50d9876cba..e3445e9e0e6 100644 --- a/src/app/Components/ArtworkGrids/GenericGrid.tsx +++ b/src/app/Components/ArtworkGrids/GenericGrid.tsx @@ -3,6 +3,7 @@ import { TextProps } from "@artsy/palette-mobile" import { GenericGrid_artworks$data } from "__generated__/GenericGrid_artworks.graphql" import Spinner from "app/Components/Spinner" import { Stack } from "app/Components/Stack" +import { AnalyticsContextProvider } from "app/system/analytics/AnalyticsContext" import { PageableRouteProps, useNavigateToPageableRoute, @@ -190,13 +191,20 @@ export class GenericArtworksGrid extends React.Component - - {artworks} + + + + {artworks} + + {this.props.isLoading ? : null} - {this.props.isLoading ? : null} - + ) } } diff --git a/src/app/Components/ArtworkGrids/InfiniteScrollArtworksGrid.tsx b/src/app/Components/ArtworkGrids/InfiniteScrollArtworksGrid.tsx index bfe6f7d4342..9be070597e9 100644 --- a/src/app/Components/ArtworkGrids/InfiniteScrollArtworksGrid.tsx +++ b/src/app/Components/ArtworkGrids/InfiniteScrollArtworksGrid.tsx @@ -12,6 +12,7 @@ import { InfiniteScrollArtworksGrid_myCollectionConnection$data } from "__genera import ParentAwareScrollView from "app/Components/ParentAwareScrollView" import { PAGE_SIZE } from "app/Components/constants" import { MyCollectionArtworkGridItemFragmentContainer } from "app/Scenes/MyCollection/Screens/ArtworkList/MyCollectionArtworkGridItem" +import { AnalyticsContextProvider } from "app/system/analytics/AnalyticsContext" import { useNavigateToPageableRoute } from "app/system/navigation/useNavigateToPageableRoute" import { extractNodes } from "app/utils/extractNodes" import { isCloseToBottom } from "app/utils/isCloseToBottom" @@ -367,7 +368,11 @@ const InfiniteScrollArtworksGrid: React.FC = ({ const ScrollViewWrapper = !!useParentAwareScrollView ? ParentAwareScrollView : ScrollView return ( - <> + { onScroll?.(ev) @@ -426,7 +431,7 @@ const InfiniteScrollArtworksGrid: React.FC = ({ {!!FooterComponent && FooterComponent} - + ) } diff --git a/src/app/Components/ArtworkLists/views/CreateNewArtworkListView/components/CreateNewArtworkListForm.tsx b/src/app/Components/ArtworkLists/views/CreateNewArtworkListView/components/CreateNewArtworkListForm.tsx index 54460418f6f..f259472b957 100644 --- a/src/app/Components/ArtworkLists/views/CreateNewArtworkListView/components/CreateNewArtworkListForm.tsx +++ b/src/app/Components/ArtworkLists/views/CreateNewArtworkListView/components/CreateNewArtworkListForm.tsx @@ -1,3 +1,4 @@ +import { ActionType, CreatedArtworkList } from "@artsy/cohesion" import { Flex, FlexProps } from "@artsy/palette-mobile" import { useBottomSheetModal } from "@gorhom/bottom-sheet" import { captureMessage } from "@sentry/react-native" @@ -9,12 +10,16 @@ import { import { ArtworkListEntity, ArtworkListMode } from "app/Components/ArtworkLists/types" import { useCreateNewArtworkList } from "app/Components/ArtworkLists/views/CreateNewArtworkListView/useCreateNewArtworkList" import { ArtworkListsViewName } from "app/Components/ArtworkLists/views/constants" +import { useAnalyticsContext } from "app/system/analytics/AnalyticsContext" import { FormikHelpers } from "formik" import { FC } from "react" +import { useTracking } from "react-tracking" export const CreateNewArtworkListForm: FC = (props) => { const { dispatch } = useArtworkListsContext() const { dismiss } = useBottomSheetModal() + const analytics = useAnalyticsContext() + const { trackEvent } = useTracking() const [commitMutation] = useCreateNewArtworkList() const setRecentlyAddedArtworkList = (artworkList: ArtworkListEntity) => { @@ -41,6 +46,18 @@ export const CreateNewArtworkListForm: FC = (props) => { dismiss(ArtworkListsViewName.CreateNewArtworkLists) } + const trackAnalyticEvent = (artworkListId: string) => { + const event: CreatedArtworkList = { + action: ActionType.createdArtworkList, + context_owner_id: analytics.contextScreenOwnerId, + context_owner_slug: analytics.contextScreenOwnerSlug, + context_owner_type: analytics.contextScreenOwnerType!, + owner_id: artworkListId, + } + + trackEvent(event) + } + const handleSubmit = ( values: CreateOrEditArtworkListFormValues, helpers: FormikHelpers @@ -62,6 +79,7 @@ export const CreateNewArtworkListForm: FC = (props) => { setRecentlyAddedArtworkList(result) preselectRecentlyAddedArtworkList(result) closeCurrentView() + trackAnalyticEvent(artworkList.internalID) helpers.setSubmitting(false) }, diff --git a/src/app/Components/ArtworkLists/views/SelectArtworkListsForArtworkView/components/SelectArtworkListsForArtworkFooter.tsx b/src/app/Components/ArtworkLists/views/SelectArtworkListsForArtworkView/components/SelectArtworkListsForArtworkFooter.tsx index d73e8078a06..ed8d490f106 100644 --- a/src/app/Components/ArtworkLists/views/SelectArtworkListsForArtworkView/components/SelectArtworkListsForArtworkFooter.tsx +++ b/src/app/Components/ArtworkLists/views/SelectArtworkListsForArtworkView/components/SelectArtworkListsForArtworkFooter.tsx @@ -1,3 +1,4 @@ +import { ActionType, AddedArtworkToArtworkList } from "@artsy/cohesion" import { Box, BoxProps, Button, Spacer, Text } from "@artsy/palette-mobile" import { useBottomSheetModal } from "@gorhom/bottom-sheet" import { captureMessage } from "@sentry/react-native" @@ -5,11 +6,15 @@ import { useArtworkListsContext } from "app/Components/ArtworkLists/ArtworkLists import { ResultAction } from "app/Components/ArtworkLists/types" import { useUpdateArtworkListsForArtwork } from "app/Components/ArtworkLists/views/SelectArtworkListsForArtworkView/useUpdateArtworkListsForArtwork" import { ArtworkListsViewName } from "app/Components/ArtworkLists/views/constants" +import { useAnalyticsContext } from "app/system/analytics/AnalyticsContext" import { FC } from "react" +import { useTracking } from "react-tracking" export const SelectArtworkListsForArtworkFooter: FC = (props) => { const { state, addingArtworkListIDs, removingArtworkListIDs, onSave } = useArtworkListsContext() const { dismiss } = useBottomSheetModal() + const { trackEvent } = useTracking() + const analytics = useAnalyticsContext() const { selectedTotalCount } = state const hasChanges = addingArtworkListIDs.length !== 0 || removingArtworkListIDs.length !== 0 const artwork = state.artwork! @@ -18,6 +23,19 @@ export const SelectArtworkListsForArtworkFooter: FC = (props) => { const [commit, mutationInProgress] = useUpdateArtworkListsForArtwork(artwork.id) + const trackAddedArtworkToArtworkLists = () => { + const event: AddedArtworkToArtworkList = { + action: ActionType.addedArtworkToArtworkList, + context_owner_id: analytics.contextScreenOwnerId, + context_owner_slug: analytics.contextScreenOwnerSlug, + context_owner_type: analytics.contextScreenOwnerType!, + artwork_ids: [artwork.internalID], + owner_ids: addingArtworkListIDs, + } + + trackEvent(event) + } + const handleSave = () => { commit({ variables: { @@ -29,6 +47,10 @@ export const SelectArtworkListsForArtworkFooter: FC = (props) => { }, }, onCompleted: () => { + if (addingArtworkListIDs.length > 0) { + trackAddedArtworkToArtworkLists() + } + dismiss(ArtworkListsViewName.SelectArtworkListsForArtwork) onSave({ action: ResultAction.ModifiedArtworkLists, diff --git a/src/app/Components/ArtworkRail/ArtworkRailCard.tsx b/src/app/Components/ArtworkRail/ArtworkRailCard.tsx index 46b6b0e01de..94fa5346309 100644 --- a/src/app/Components/ArtworkRail/ArtworkRailCard.tsx +++ b/src/app/Components/ArtworkRail/ArtworkRailCard.tsx @@ -9,6 +9,7 @@ import { useSaveArtworkToArtworkLists } from "app/Components/ArtworkLists/useSav import { useExtraLargeWidth } from "app/Components/ArtworkRail/useExtraLargeWidth" import { ContextMenuArtwork } from "app/Components/ContextMenu/ContextMenuArtwork" import OpaqueImageView from "app/Components/OpaqueImageView/OpaqueImageView" +import { AnalyticsContextProvider } from "app/system/analytics/AnalyticsContext" import { getUrgencyTag } from "app/utils/getUrgencyTag" import { ArtworkActionTrackingProps, @@ -89,6 +90,14 @@ export const ArtworkRailCard: React.FC = ({ const secondaryTextColor = dark ? "black15" : "black60" const backgroundColor = dark ? "black100" : "white100" + const { + contextModule, + contextScreenOwnerType, + contextScreenOwnerId, + contextScreenOwnerSlug, + contextScreen, + } = restProps + const getTextHeightByArtworkSize = (cardSize: ArtworkCardSize) => { if (cardSize === "small") { return ARTWORK_RAIL_TEXT_CONTAINER_HEIGHT + 30 @@ -139,13 +148,6 @@ export const ArtworkRailCard: React.FC = ({ }, [image?.resized?.height, image?.resized?.width]) const onArtworkSavedOrUnSaved = (saved: boolean) => { - const { - contextModule, - contextScreenOwnerType, - contextScreenOwnerId, - contextScreenOwnerSlug, - contextScreen, - } = restProps const { availability, isAcquireable, isBiddable, isInquireable, isOfferable } = artwork const params = { acquireable: isAcquireable, @@ -173,7 +175,11 @@ export const ArtworkRailCard: React.FC = ({ !!isRecentlySoldArtwork && (size === "large" || size === "extraLarge") return ( - <> + setShowCreateArtworkAlertModal(true)} artwork={artwork} @@ -310,7 +316,7 @@ export const ArtworkRailCard: React.FC = ({ onClose={() => setShowCreateArtworkAlertModal(false)} visible={showCreateArtworkAlertModal} /> - + ) } diff --git a/src/app/Components/SaleArtworkTileRailCard/SaleArtworkTileRailCard.tsx b/src/app/Components/SaleArtworkTileRailCard/SaleArtworkTileRailCard.tsx index 2020ee5efdd..91fc98a2347 100644 --- a/src/app/Components/SaleArtworkTileRailCard/SaleArtworkTileRailCard.tsx +++ b/src/app/Components/SaleArtworkTileRailCard/SaleArtworkTileRailCard.tsx @@ -12,6 +12,7 @@ import { saleMessageOrBidInfo } from "app/Components/ArtworkGrids/ArtworkGridIte import { CARD_WIDTH } from "app/Components/Home/CardRailCard" import OpaqueImageView from "app/Components/OpaqueImageView/OpaqueImageView" import { UrgencyInfo } from "app/Components/SaleArtworkTileRailCard/UrgencyInfo" +import { AnalyticsContextProvider } from "app/system/analytics/AnalyticsContext" import { useFeatureFlag } from "app/utils/hooks/useFeatureFlag" import { createFragmentContainer, graphql } from "react-relay" import { useTracking } from "react-tracking" @@ -158,26 +159,32 @@ export const SaleArtworkTileRailCard: React.FC = ( ) : null return ( - - - {imageDisplay} - - {lotNumber} - {artistNamesDisplay} - {titleAndDateDisplay} - {customSaleMessage ? customSaleMessageDisplay : saleMessageDisplay} - {!!enableNewSaleArtworkTileRailCard && ( - - )} - - - + + + + {imageDisplay} + + {lotNumber} + {artistNamesDisplay} + {titleAndDateDisplay} + {customSaleMessage ? customSaleMessageDisplay : saleMessageDisplay} + {!!enableNewSaleArtworkTileRailCard && ( + + )} + + + + ) } diff --git a/src/app/Scenes/Artwork/Artwork.tsx b/src/app/Scenes/Artwork/Artwork.tsx index fee09266d7b..89be7ce2334 100644 --- a/src/app/Scenes/Artwork/Artwork.tsx +++ b/src/app/Scenes/Artwork/Artwork.tsx @@ -15,6 +15,7 @@ import { ArtistSeriesMoreSeriesFragmentContainer as ArtistSeriesMoreSeries } fro import { ArtworkScreenHeader } from "app/Scenes/Artwork/Components/ArtworkScreenHeader" import { OfferSubmittedModal } from "app/Scenes/Inbox/Components/Conversations/OfferSubmittedModal" import { GlobalStore } from "app/store/GlobalStore" +import { AnalyticsContextProvider } from "app/system/analytics/AnalyticsContext" import { navigationEvents } from "app/system/navigation/navigate" import { getRelayEnvironment } from "app/system/relay/defaultEnvironment" import { AboveTheFoldQueryRenderer } from "app/utils/AboveTheFoldQueryRenderer" @@ -468,18 +469,24 @@ const ArtworkProvidersContainer: React.FC = (props) => { return ( - - - - - - - + + + + + + + + + ) } diff --git a/src/app/Scenes/ArtworkList/ArtworkList.tsx b/src/app/Scenes/ArtworkList/ArtworkList.tsx index 559fb4e76a5..644bda1a4ea 100644 --- a/src/app/Scenes/ArtworkList/ArtworkList.tsx +++ b/src/app/Scenes/ArtworkList/ArtworkList.tsx @@ -1,4 +1,4 @@ -import { ActionType, OwnerType, ViewedArtworkList } from "@artsy/cohesion" +import { OwnerType } from "@artsy/cohesion" import { Flex, Separator, useScreenDimensions, useSpace } from "@artsy/palette-mobile" import { ArtworkListQuery, CollectionArtworkSorts } from "__generated__/ArtworkListQuery.graphql" import { ArtworkList_artworksConnection$key } from "__generated__/ArtworkList_artworksConnection.graphql" @@ -12,9 +12,10 @@ import { ArtworkListEmptyState } from "app/Scenes/ArtworkList/ArtworkListEmptySt import { ArtworkListHeader } from "app/Scenes/ArtworkList/ArtworkListHeader" import { PlaceholderText, ProvidePlaceholderContext } from "app/utils/placeholders" import { useRefreshControl } from "app/utils/refreshHelpers" -import { FC, Suspense, useEffect, useState } from "react" +import { ProvideScreenTrackingWithCohesionSchema } from "app/utils/track" +import { screen } from "app/utils/track/helpers" +import { FC, Suspense, useState } from "react" import { graphql, useLazyLoadQuery, usePaginationFragment } from "react-relay" -import { useTracking } from "react-tracking" import usePrevious from "react-use/lib/usePrevious" interface ArtworkListScreenProps { @@ -157,22 +158,17 @@ const artworkListFragment = graphql` ` export const ArtworkListScreen: FC = (props) => { - const { trackEvent } = useTracking() - - useEffect(() => { - const event: ViewedArtworkList = { - action: ActionType.viewedArtworkList, - context_owner_type: OwnerType.saves, - owner_id: props.listID, - } - - trackEvent(event) - }, [props.listID, trackEvent]) - return ( - }> - - + + }> + + + ) } diff --git a/src/app/Scenes/Sale/Components/SaleArtworkListItem.tsx b/src/app/Scenes/Sale/Components/SaleArtworkListItem.tsx index b40725adc88..401b73ff5ad 100644 --- a/src/app/Scenes/Sale/Components/SaleArtworkListItem.tsx +++ b/src/app/Scenes/Sale/Components/SaleArtworkListItem.tsx @@ -5,13 +5,13 @@ import { tappedEntityGroup, TappedEntityGroupArgs, } from "@artsy/cohesion" -import { Flex, Text } from "@artsy/palette-mobile" +import { Flex, Text, Touchable } from "@artsy/palette-mobile" import { SaleArtworkListItem_artwork$data } from "__generated__/SaleArtworkListItem_artwork.graphql" import { saleMessageOrBidInfo } from "app/Components/ArtworkGrids/ArtworkGridItem" import OpaqueImageView from "app/Components/OpaqueImageView/OpaqueImageView" +import { AnalyticsContextProvider } from "app/system/analytics/AnalyticsContext" import { navigate } from "app/system/navigation/navigate" import { getImageSquareDimensions } from "app/utils/resizeImage" -import { Touchable } from "@artsy/palette-mobile" import React, { useRef } from "react" import { createFragmentContainer, graphql } from "react-relay" import { useTracking } from "react-tracking" @@ -60,49 +60,55 @@ export const SaleArtworkListItem: React.FC = ({ artwork, contextScreenOwn ) return ( - - - {!!artwork.image && ( - - - - )} - - - {!!artwork.saleArtwork?.lotLabel && ( - - Lot {artwork.saleArtwork.lotLabel} - - )} - {!!artwork.artistNames && ( - - {artwork.artistNames} - - )} - {!!artwork.title && ( - - {artwork.title} - {!!artwork.date && `, ${artwork.date}`} - - )} - {!!saleInfo && ( - - {saleInfo} - + + + + {!!artwork.image && ( + + + )} + + + {!!artwork.saleArtwork?.lotLabel && ( + + Lot {artwork.saleArtwork.lotLabel} + + )} + {!!artwork.artistNames && ( + + {artwork.artistNames} + + )} + {!!artwork.title && ( + + {artwork.title} + {!!artwork.date && `, ${artwork.date}`} + + )} + {!!saleInfo && ( + + {saleInfo} + + )} + - - + + ) } diff --git a/src/app/system/analytics/AnalyticsContext.tsx b/src/app/system/analytics/AnalyticsContext.tsx new file mode 100644 index 00000000000..0d9d5163e12 --- /dev/null +++ b/src/app/system/analytics/AnalyticsContext.tsx @@ -0,0 +1,18 @@ +import { ScreenOwnerType } from "@artsy/cohesion" +import { FC, createContext, useContext } from "react" + +export interface AnalyticsContextProps { + contextScreenOwnerId?: string + contextScreenOwnerSlug?: string + contextScreenOwnerType?: ScreenOwnerType +} + +const AnalyticsContext = createContext({}) + +export const AnalyticsContextProvider: FC = ({ children, ...rest }) => { + return {children} +} + +export const useAnalyticsContext = () => { + return useContext(AnalyticsContext) +}