Skip to content

Commit

Permalink
chore(FX-4795): artwork list analytics (stage 2) (#8764)
Browse files Browse the repository at this point in the history
* feat: track `addedArtworkToArtworkList`

* feat: add `AnalyticsContext`

* chore: remove TODO comment

* refactor: use `Screen` prefix

* chore: use `ProvideScreenTrackingWithCohesionSchema`
  • Loading branch information
dimatretyak committed May 26, 2023
1 parent 4f42400 commit 8120e50
Show file tree
Hide file tree
Showing 10 changed files with 202 additions and 109 deletions.
18 changes: 13 additions & 5 deletions src/app/Components/ArtworkGrids/GenericGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -190,13 +191,20 @@ export class GenericArtworksGrid extends React.Component<Props & PropsForArtwork

render() {
const artworks = this.state.sectionDimension ? this.renderSections() : null

return (
<View onLayout={this.onLayout}>
<View style={styles.container} accessibilityLabel="Artworks Content View">
{artworks}
<AnalyticsContextProvider
contextScreenOwnerId={this.props.contextScreenOwnerId}
contextScreenOwnerSlug={this.props.contextScreenOwnerSlug}
contextScreenOwnerType={this.props.contextScreenOwnerType}
>
<View onLayout={this.onLayout}>
<View style={styles.container} accessibilityLabel="Artworks Content View">
{artworks}
</View>
{this.props.isLoading ? <Spinner style={styles.spinner} /> : null}
</View>
{this.props.isLoading ? <Spinner style={styles.spinner} /> : null}
</View>
</AnalyticsContextProvider>
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -367,7 +368,11 @@ const InfiniteScrollArtworksGrid: React.FC<Props & PrivateProps> = ({
const ScrollViewWrapper = !!useParentAwareScrollView ? ParentAwareScrollView : ScrollView

return (
<>
<AnalyticsContextProvider
contextScreenOwnerType={contextScreenOwnerType}
contextScreenOwnerId={contextScreenOwnerId}
contextScreenOwnerSlug={contextScreenOwnerSlug}
>
<ScrollViewWrapper
onScroll={(ev) => {
onScroll?.(ev)
Expand Down Expand Up @@ -426,7 +431,7 @@ const InfiniteScrollArtworksGrid: React.FC<Props & PrivateProps> = ({
</ScrollViewWrapper>

{!!FooterComponent && FooterComponent}
</>
</AnalyticsContextProvider>
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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<FlexProps> = (props) => {
const { dispatch } = useArtworkListsContext()
const { dismiss } = useBottomSheetModal()
const analytics = useAnalyticsContext()
const { trackEvent } = useTracking()
const [commitMutation] = useCreateNewArtworkList()

const setRecentlyAddedArtworkList = (artworkList: ArtworkListEntity) => {
Expand All @@ -41,6 +46,18 @@ export const CreateNewArtworkListForm: FC<FlexProps> = (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<CreateOrEditArtworkListFormValues>
Expand All @@ -62,6 +79,7 @@ export const CreateNewArtworkListForm: FC<FlexProps> = (props) => {
setRecentlyAddedArtworkList(result)
preselectRecentlyAddedArtworkList(result)
closeCurrentView()
trackAnalyticEvent(artworkList.internalID)

helpers.setSubmitting(false)
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
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"
import { useArtworkListsContext } from "app/Components/ArtworkLists/ArtworkListsContext"
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<BoxProps> = (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!
Expand All @@ -18,6 +23,19 @@ export const SelectArtworkListsForArtworkFooter: FC<BoxProps> = (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: {
Expand All @@ -29,6 +47,10 @@ export const SelectArtworkListsForArtworkFooter: FC<BoxProps> = (props) => {
},
},
onCompleted: () => {
if (addingArtworkListIDs.length > 0) {
trackAddedArtworkToArtworkLists()
}

dismiss(ArtworkListsViewName.SelectArtworkListsForArtwork)
onSave({
action: ResultAction.ModifiedArtworkLists,
Expand Down
24 changes: 15 additions & 9 deletions src/app/Components/ArtworkRail/ArtworkRailCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -89,6 +90,14 @@ export const ArtworkRailCard: React.FC<ArtworkRailCardProps> = ({
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
Expand Down Expand Up @@ -139,13 +148,6 @@ export const ArtworkRailCard: React.FC<ArtworkRailCardProps> = ({
}, [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,
Expand Down Expand Up @@ -173,7 +175,11 @@ export const ArtworkRailCard: React.FC<ArtworkRailCardProps> = ({
!!isRecentlySoldArtwork && (size === "large" || size === "extraLarge")

return (
<>
<AnalyticsContextProvider
contextScreenOwnerId={contextScreenOwnerId}
contextScreenOwnerSlug={contextScreenOwnerSlug}
contextScreenOwnerType={contextScreenOwnerType}
>
<ContextMenuArtwork
onCreateAlertActionPress={() => setShowCreateArtworkAlertModal(true)}
artwork={artwork}
Expand Down Expand Up @@ -310,7 +316,7 @@ export const ArtworkRailCard: React.FC<ArtworkRailCardProps> = ({
onClose={() => setShowCreateArtworkAlertModal(false)}
visible={showCreateArtworkAlertModal}
/>
</>
</AnalyticsContextProvider>
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -158,26 +159,32 @@ export const SaleArtworkTileRailCard: React.FC<SaleArtworkTileRailCardProps> = (
) : null

return (
<SaleArtworkCard onPress={handleTap}>
<Flex>
{imageDisplay}
<Box mt={1} width={IMAGE_CONTAINER_WIDTH}>
{lotNumber}
{artistNamesDisplay}
{titleAndDateDisplay}
{customSaleMessage ? customSaleMessageDisplay : saleMessageDisplay}
{!!enableNewSaleArtworkTileRailCard && (
<UrgencyInfo
startAt={startAt}
endAt={endAt}
isLiveAuction={!!saleArtwork.sale?.liveStartAt}
saleTimeZone={saleArtwork.sale?.timeZone ?? ""}
onTimerEnd={refreshRail}
/>
)}
</Box>
</Flex>
</SaleArtworkCard>
<AnalyticsContextProvider
contextScreenOwnerId={artwork.internalID}
contextScreenOwnerSlug={artwork.slug}
contextScreenOwnerType={OwnerType.sale}
>
<SaleArtworkCard onPress={handleTap}>
<Flex>
{imageDisplay}
<Box mt={1} width={IMAGE_CONTAINER_WIDTH}>
{lotNumber}
{artistNamesDisplay}
{titleAndDateDisplay}
{customSaleMessage ? customSaleMessageDisplay : saleMessageDisplay}
{!!enableNewSaleArtworkTileRailCard && (
<UrgencyInfo
startAt={startAt}
endAt={endAt}
isLiveAuction={!!saleArtwork.sale?.liveStartAt}
saleTimeZone={saleArtwork.sale?.timeZone ?? ""}
onTimerEnd={refreshRail}
/>
)}
</Box>
</Flex>
</SaleArtworkCard>
</AnalyticsContextProvider>
)
}

Expand Down
31 changes: 19 additions & 12 deletions src/app/Scenes/Artwork/Artwork.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -468,18 +469,24 @@ const ArtworkProvidersContainer: React.FC<ArtworkProps> = (props) => {

return (
<ProvideScreenTracking info={trackingInfo}>
<AuctionWebsocketContextProvider channelInfo={socketChannelInfo} enabled={websocketEnabled}>
<ArtworkStoreProvider
runtimeModel={{
...artworkModel,
auctionState: getInitialAuctionTimerState()!,
}}
>
<ArtworkListsProvider>
<Artwork {...props} />
</ArtworkListsProvider>
</ArtworkStoreProvider>
</AuctionWebsocketContextProvider>
<AnalyticsContextProvider
contextScreenOwnerId={artworkAboveTheFold?.internalID}
contextScreenOwnerSlug={artworkAboveTheFold?.slug}
contextScreenOwnerType={OwnerType.artwork}
>
<AuctionWebsocketContextProvider channelInfo={socketChannelInfo} enabled={websocketEnabled}>
<ArtworkStoreProvider
runtimeModel={{
...artworkModel,
auctionState: getInitialAuctionTimerState()!,
}}
>
<ArtworkListsProvider>
<Artwork {...props} />
</ArtworkListsProvider>
</ArtworkStoreProvider>
</AuctionWebsocketContextProvider>
</AnalyticsContextProvider>
</ProvideScreenTracking>
)
}
Expand Down
32 changes: 14 additions & 18 deletions src/app/Scenes/ArtworkList/ArtworkList.tsx
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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 {
Expand Down Expand Up @@ -157,22 +158,17 @@ const artworkListFragment = graphql`
`

export const ArtworkListScreen: FC<ArtworkListScreenProps> = (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 (
<Suspense fallback={<ArtworkListPlaceholder />}>
<ArtworkList {...props} />
</Suspense>
<ProvideScreenTrackingWithCohesionSchema
info={screen({
context_screen_owner_type: OwnerType.saves,
context_screen_owner_id: props.listID,
})}
>
<Suspense fallback={<ArtworkListPlaceholder />}>
<ArtworkList {...props} />
</Suspense>
</ProvideScreenTrackingWithCohesionSchema>
)
}

Expand Down
Loading

0 comments on commit 8120e50

Please sign in to comment.