Skip to content

Commit

Permalink
feat(ONYX-1294): redesign badges and urgency signals on artwork card (#…
Browse files Browse the repository at this point in the history
…11005)

* feat: redesign Curators Pick and Increased Interest

* feat: redesign partner offer

* feat: redesign hight demand indicator, chore

* chore: address review comments

* chore: extract ArtworkSaleMessageComponent into a separate component

* fix: tests

* chore: refactoring

* chore: address review comments

* chore: address review comments

* chore: rename ArtworkSaleMessage Component
  • Loading branch information
dariakoko authored Oct 25, 2024
1 parent 34f483a commit 18cab4f
Show file tree
Hide file tree
Showing 14 changed files with 234 additions and 156 deletions.
2 changes: 1 addition & 1 deletion .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -1134,5 +1134,5 @@
}
]
},
"generated_at": "2024-09-11T13:12:04Z"
"generated_at": "2024-10-24T13:23:36Z"
}
5 changes: 3 additions & 2 deletions src/app/Components/ArtworkGrids/ArtworkGridItem.tests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -491,14 +491,15 @@ describe("ArtworkGridItem", () => {
renderWithRelay({
Artwork: () => ({
...artwork,
saleMessage: "$120,500",
sale: { ...artwork.sale, isAuction: false },
realizedPrice: null,
collectorSignals,
}),
})

expect(screen.getByText("Limited-Time Offer")).toBeOnTheScreen()
expect(screen.getByText("Exp. 1d 12h")).toBeOnTheScreen()
expect(screen.getByText("$120,500")).toBeOnTheScreen()
expect(screen.getByText("Offer Expires 1d 12h")).toBeOnTheScreen()
})

it("doesn't show the limited-time offer signal for auction artworks", () => {
Expand Down
67 changes: 19 additions & 48 deletions src/app/Components/ArtworkGrids/ArtworkGridItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ import { ArtworksFiltersStore } from "app/Components/ArtworkFilter/ArtworkFilter
import { ArtworkAuctionTimer } from "app/Components/ArtworkGrids/ArtworkAuctionTimer"
import { ArtworkSocialSignal } from "app/Components/ArtworkGrids/ArtworkSocialSignal"
import { useSaveArtworkToArtworkLists } from "app/Components/ArtworkLists/useSaveArtworkToArtworkLists"
import { ArtworkSaleMessage } from "app/Components/ArtworkRail/ArtworkSaleMessage"
import { ContextMenuArtwork } from "app/Components/ContextMenu/ContextMenuArtwork"
import { DurationProvider } from "app/Components/Countdown"
import { Disappearable, DissapearableArtwork } from "app/Components/Disappearable"
import { ProgressiveOnboardingSaveArtwork } from "app/Components/ProgressiveOnboarding/ProgressiveOnboardingSaveArtwork"
import { HEART_ICON_SIZE } from "app/Components/constants"
import { PartnerOffer } from "app/Scenes/Activity/components/NotificationArtworkList"
import { formattedTimeLeft } from "app/Scenes/Activity/utils/formattedTimeLeft"
import { GlobalStore } from "app/store/GlobalStore"
import { navigate } from "app/system/navigation/navigate"
import { useArtworkBidding } from "app/utils/Websockets/auctions/useArtworkBidding"
Expand Down Expand Up @@ -252,10 +252,6 @@ export const Artwork: React.FC<ArtworkProps> = ({
? currentBiddingEndAt
: artwork.saleArtwork?.endAt || artwork.sale?.endAt

const partnerOfferEndAt = collectorSignals?.partnerOffer?.endAt
? formattedTimeLeft(getTimer(collectorSignals.partnerOffer.endAt).time).timerCopy
: ""

const urgencyTag = getUrgencyTag(endsAt)

const canShowAuctionProgressBar =
Expand All @@ -271,16 +267,13 @@ export const Artwork: React.FC<ArtworkProps> = ({

const displayAuctionSignal = AREnableAuctionImprovementsSignals && isAuction

const saleInfoTextColor =
displayAuctionSignal && collectorSignals?.auction?.liveBiddingStarted ? "blue100" : "black100"

const saleInfoTextWeight =
displayAuctionSignal && collectorSignals?.auction?.liveBiddingStarted ? "normal" : "bold"

const handleSupress = async (item: DissapearableArtwork) => {
await item._disappearable?.disappear()
}

const displayArtworkSocialSignal =
!isAuction && !displayLimitedTimeOfferSignal && !!collectorSignals

return (
<Disappearable ref={(ref) => ((artwork as any)._disappearable = ref)}>
<ContextMenuArtwork
Expand Down Expand Up @@ -354,20 +347,6 @@ export const Artwork: React.FC<ArtworkProps> = ({
style={artworkMetaStyle}
>
<Flex flex={1}>
{!!displayLimitedTimeOfferSignal && (
<Box backgroundColor="blue10" px={0.5} alignSelf="flex-start" borderRadius={3}>
<Text lineHeight="20px" variant="xs" color="blue100">
Limited-Time Offer
</Text>
</Box>
)}
{!isAuction && !displayLimitedTimeOfferSignal && !!collectorSignals && (
<ArtworkSocialSignal
collectorSignals={collectorSignals}
hideCuratorsPick={hideCuratorsPickSignal}
hideIncreasedInterest={hideIncreasedInterestSignal}
/>
)}
{!!showLotLabel && !!artwork.saleArtwork?.lotLabel && (
<>
<Text variant="xs" numberOfLines={1} caps {...lotLabelTextStyle}>
Expand Down Expand Up @@ -435,29 +414,12 @@ export const Artwork: React.FC<ArtworkProps> = ({
</Flex>
)}
{!!saleInfo && !hideSaleInfo && !displayPriceOfferMessage && (
<Text
lineHeight="18px"
variant="xs"
numberOfLines={1}
color={saleInfoTextColor}
fontWeight={saleInfoTextWeight}
{...saleInfoTextStyle}
>
{saleInfo}
{!!displayLimitedTimeOfferSignal && (
<Text
lineHeight="18px"
variant="xs"
weight="regular"
numberOfLines={1}
color="blue100"
{...saleInfoTextStyle}
>
{" "}
Exp. {partnerOfferEndAt}
</Text>
)}
</Text>
<ArtworkSaleMessage
artwork={artwork}
saleMessage={saleInfo}
displayLimitedTimeOfferSignal={displayLimitedTimeOfferSignal}
saleInfoTextStyle={saleInfoTextStyle}
/>
)}

{!!artwork.isUnlisted && (
Expand All @@ -472,6 +434,14 @@ export const Artwork: React.FC<ArtworkProps> = ({
hideRegisterBySignal={hideRegisterBySignal}
/>
)}

{!!displayArtworkSocialSignal && (
<ArtworkSocialSignal
collectorSignals={collectorSignals}
hideCuratorsPick={hideCuratorsPickSignal}
hideIncreasedInterest={hideIncreasedInterestSignal}
/>
)}
</Flex>
{!hideSaveIcon && (
<Flex flexDirection="row" alignItems="flex-start">
Expand Down Expand Up @@ -609,6 +579,7 @@ export default createFragmentContainer(Artwork, {
...ArtworkAuctionTimer_collectorSignals
...ArtworkSocialSignal_collectorSignals
}
...ArtworkSaleMessage_artwork
...useSaveArtworkToArtworkLists_artwork
}
`,
Expand Down
28 changes: 9 additions & 19 deletions src/app/Components/ArtworkGrids/ArtworkSocialSignal.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, Text } from "@artsy/palette-mobile"
import { ArrowUpRightIcon, Box, FireIcon, Text } from "@artsy/palette-mobile"
import { ArtworkSocialSignal_collectorSignals$key } from "__generated__/ArtworkSocialSignal_collectorSignals.graphql"
import { graphql, useFragment } from "react-relay"

Expand All @@ -21,31 +21,21 @@ export const ArtworkSocialSignal: React.FC<ArtworkSocialSignalProps> = ({
switch (true) {
case curatorsPick && !hideCuratorsPick:
return (
<Box
px={0.5}
pb="2px"
alignSelf="flex-start"
borderRadius={3}
borderWidth={1}
borderColor={primaryColor}
>
<Text color={primaryColor} variant="xxs">
<Box alignItems="center" flexDirection="row">
<FireIcon />
<Text color={primaryColor} variant="xs" textAlign="center">
{" "}
Curators’ Pick
</Text>
</Box>
)

case increasedInterest && !hideIncreasedInterest:
return (
<Box
px={0.5}
pb="2px"
alignSelf="flex-start"
borderRadius={3}
borderWidth={1}
borderColor={primaryColor}
>
<Text color={primaryColor} variant="xxs">
<Box flexDirection="row" alignItems="center">
<ArrowUpRightIcon />
<Text color={primaryColor} variant="xs">
{" "}
Increased Interest
</Text>
</Box>
Expand Down
5 changes: 3 additions & 2 deletions src/app/Components/ArtworkRail/ArtworkRailCard.tests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,15 @@ describe("ArtworkRailCard", () => {
renderWithRelay({
Artwork: () => ({
...artwork,
saleMessage: "$120,500",
sale: { ...artwork.sale, isAuction: false },
realizedPrice: null,
collectorSignals,
}),
})

expect(screen.getByText("Limited-Time Offer")).toBeOnTheScreen()
expect(screen.getByText("Exp. 1d 12h")).toBeOnTheScreen()
expect(screen.getByText("$120,500")).toBeOnTheScreen()
expect(screen.getByText("Offer Expires 1d 12h")).toBeOnTheScreen()
})

it("doesn't show the limited-time offer signal for auction artworks", () => {
Expand Down
84 changes: 25 additions & 59 deletions src/app/Components/ArtworkRail/ArtworkRailCardMeta.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { Box, Flex, HeartFillIcon, HeartIcon, Text, Touchable } from "@artsy/palette-mobile"
import { Flex, HeartFillIcon, HeartIcon, Text, Touchable } from "@artsy/palette-mobile"
import { ArtworkRailCardMeta_artwork$key } from "__generated__/ArtworkRailCardMeta_artwork.graphql"
import { ArtworkAuctionTimer } from "app/Components/ArtworkGrids/ArtworkAuctionTimer"
import { ArtworkSocialSignal } from "app/Components/ArtworkGrids/ArtworkSocialSignal"
import { useSaveArtworkToArtworkLists } from "app/Components/ArtworkLists/useSaveArtworkToArtworkLists"
import { ARTWORK_RAIL_TEXT_CONTAINER_HEIGHT } from "app/Components/ArtworkRail/ArtworkRailCard"
import { useMetaDataTextColor } from "app/Components/ArtworkRail/ArtworkRailUtils"
import { ArtworkSaleMessage } from "app/Components/ArtworkRail/ArtworkSaleMessage"
import { HEART_ICON_SIZE } from "app/Components/constants"
import { formattedTimeLeft } from "app/Scenes/Activity/utils/formattedTimeLeft"
import { saleMessageOrBidInfo as defaultSaleMessageOrBidInfo } from "app/utils/getSaleMessgeOrBidInfo"
import { getTimer } from "app/utils/getTimer"
import { saleMessageOrBidInfo } from "app/utils/getSaleMessgeOrBidInfo"
import { useFeatureFlag } from "app/utils/hooks/useFeatureFlag"
import {
ArtworkActionTrackingProps,
Expand Down Expand Up @@ -79,33 +79,20 @@ export const ArtworkRailCardMeta: React.FC<ArtworkRailCardMetaProps> = ({
collectorSignals,
} = artwork

const saleMessage = defaultSaleMessageOrBidInfo({
const saleMessage = saleMessageOrBidInfo({
artwork,
isSmallTile: true,
collectorSignals: collectorSignals,
auctionSignals: enableAuctionImprovementsSignals ? collectorSignals?.auction : null,
})

const partnerOfferEndAt = collectorSignals?.partnerOffer?.endAt
? formattedTimeLeft(getTimer(collectorSignals.partnerOffer.endAt).time).timerCopy
: ""

const primaryTextColor = dark ? "white100" : "black100"
const secondaryTextColor = dark ? "black15" : "black60"
const { primaryTextColor, secondaryTextColor } = useMetaDataTextColor({ dark })

const displayLimitedTimeOfferSignal =
collectorSignals?.partnerOffer?.isAvailable && !sale?.isAuction

const displayAuctionSignal = enableAuctionImprovementsSignals && sale?.isAuction

const saleInfoTextColor =
displayAuctionSignal && collectorSignals?.auction?.liveBiddingStarted
? "blue100"
: primaryTextColor

const saleInfoTextWeight =
displayAuctionSignal && collectorSignals?.auction?.liveBiddingStarted ? "normal" : "bold"

const onArtworkSavedOrUnSaved = (saved: boolean) => {
trackEvent(
artworkActionTracks.saveOrUnsaveArtwork(saved, {
Expand All @@ -128,6 +115,9 @@ export const ArtworkRailCardMeta: React.FC<ArtworkRailCardMetaProps> = ({
onCompleted: onArtworkSavedOrUnSaved,
})

const displayArtworkSocialSignal =
!sale?.isAuction && !displayLimitedTimeOfferSignal && !!collectorSignals

return (
<Flex
my={1}
Expand All @@ -140,23 +130,6 @@ export const ArtworkRailCardMeta: React.FC<ArtworkRailCardMetaProps> = ({
justifyContent="space-between"
>
<Flex flex={1} backgroundColor={backgroundColor}>
{!!displayLimitedTimeOfferSignal && (
<Box backgroundColor="blue10" px={0.5} alignSelf="flex-start" borderRadius={3}>
<Text lineHeight="20px" variant="xs" color="blue100">
Limited-Time Offer
</Text>
</Box>
)}

{!sale?.isAuction && !displayLimitedTimeOfferSignal && !!collectorSignals && (
<ArtworkSocialSignal
collectorSignals={collectorSignals}
hideCuratorsPick={hideCuratorsPickSignal}
hideIncreasedInterest={hideIncreasedInterestSignal}
dark={dark}
/>
)}

{!!lotLabel && (
<Text lineHeight="20px" color={secondaryTextColor} numberOfLines={1}>
Lot {lotLabel}
Expand Down Expand Up @@ -196,28 +169,12 @@ export const ArtworkRailCardMeta: React.FC<ArtworkRailCardMetaProps> = ({
{SalePriceComponent
? SalePriceComponent
: !!saleMessage && (
<Text
lineHeight="20px"
variant="xs"
color={saleInfoTextColor}
numberOfLines={1}
fontWeight={saleInfoTextWeight}
>
{saleMessage}

{!!displayLimitedTimeOfferSignal && (
<Text
lineHeight="20px"
variant="xs"
fontWeight="normal"
color="blue100"
numberOfLines={1}
>
{" "}
Exp. {partnerOfferEndAt}
</Text>
)}
</Text>
<ArtworkSaleMessage
artwork={artwork}
saleMessage={saleMessage}
displayLimitedTimeOfferSignal={displayLimitedTimeOfferSignal}
dark={dark}
/>
)}

{!!isUnlisted && (
Expand All @@ -235,6 +192,15 @@ export const ArtworkRailCardMeta: React.FC<ArtworkRailCardMetaProps> = ({
{!!displayAuctionSignal && !!collectorSignals && (
<ArtworkAuctionTimer collectorSignals={collectorSignals} inRailCard />
)}

{!!displayArtworkSocialSignal && (
<ArtworkSocialSignal
collectorSignals={collectorSignals}
hideCuratorsPick={hideCuratorsPickSignal}
hideIncreasedInterest={hideIncreasedInterestSignal}
dark={dark}
/>
)}
</Flex>

{!!showSaveIcon && (
Expand Down Expand Up @@ -290,7 +256,6 @@ const artworkMetaFragment = graphql`
sale {
isAuction
isClosed
endAt
}
saleArtwork {
currentBid {
Expand Down Expand Up @@ -325,6 +290,7 @@ const artworkMetaFragment = graphql`
...ArtworkSocialSignal_collectorSignals
}
...ArtworkSaleMessage_artwork
...useSaveArtworkToArtworkLists_artwork
}
`
9 changes: 9 additions & 0 deletions src/app/Components/ArtworkRail/ArtworkRailUtils.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const useMetaDataTextColor = ({ dark }: { dark: boolean }) => {
const primaryTextColor = dark ? "white100" : "black100"

const secondaryTextColor = dark ? "black15" : "black60"

const backgroundColor = dark ? "black100" : "white100"

return { primaryTextColor, secondaryTextColor, backgroundColor }
}
Loading

0 comments on commit 18cab4f

Please sign in to comment.