Skip to content

Commit

Permalink
fix: restore image fallbacks (#11307)
Browse files Browse the repository at this point in the history
* add fallback image and use in ThreeUpImageLayout

* add fallback image in places we added url checks

* few missed images

* fix imports

* add test for fallback image
  • Loading branch information
brainbicycle authored and MounirDhahri committed Dec 18, 2024
1 parent 465b008 commit 1d1f97e
Show file tree
Hide file tree
Showing 15 changed files with 117 additions and 65 deletions.
19 changes: 9 additions & 10 deletions src/app/Components/Artist/ArtistShows/ArtistShow.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ActionType, ContextModule, OwnerType, TappedShowGroup } from "@artsy/cohesion"
import { Image, Touchable } from "@artsy/palette-mobile"
import { Touchable } from "@artsy/palette-mobile"
import { ArtistShow_show$data, ArtistShow_show$key } from "__generated__/ArtistShow_show.graphql"
import { ImageWithFallback } from "app/Components/ImageWithFallback/ImageWithFallback"
import { navigate } from "app/system/navigation/navigate"
import { useFeatureFlag } from "app/utils/hooks/useFeatureFlag"
import { hrefForPartialShow } from "app/utils/router"
Expand Down Expand Up @@ -41,15 +42,13 @@ export const ArtistShow: React.FC<Props> = ({ styles, show, index, imageDimensio
<Touchable onPress={handleTap} haptic>
<View style={[styles?.container]}>
<View style={[styles?.imageMargin]}>
{!!imageURL && (
<Image
src={imageURL}
width={imageDimensions.width}
height={imageDimensions.height}
blurhash={showBlurhash ? image?.blurhash : undefined}
style={[{ overflow: "hidden", borderRadius: 2, flex: 0 }]}
/>
)}
<ImageWithFallback
src={imageURL}
width={imageDimensions.width}
height={imageDimensions.height}
blurhash={showBlurhash ? image?.blurhash : undefined}
style={[{ overflow: "hidden", borderRadius: 2, flex: 0 }]}
/>
</View>
{/* this wrapper required to make numberOfLines work when parent is a row */}
<View style={{ flex: 1 }}>
Expand Down
23 changes: 23 additions & 0 deletions src/app/Components/ImageWithFallback/ImageWithFallback.tests.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ImageWithFallback } from "app/Components/ImageWithFallback/ImageWithFallback"
import { renderWithWrappers } from "app/utils/tests/renderWithWrappers"

describe("ImageWithFallback", () => {
it("renders without error", () => {
renderWithWrappers(<ImageWithFallback />)
})

it("renders the image when a url is passed", async () => {
const view = renderWithWrappers(
<ImageWithFallback src="https://example.com/image.jpg" width={100} height={100} />
)
const image = await view.findByTestId("image")
expect(image).toBeTruthy()
})

it("renders the fallback when a url is not passed", async () => {
const view = renderWithWrappers(<ImageWithFallback width={100} height={100} />)

const fallbackImage = await view.findByTestId("fallback-image")
expect(fallbackImage).toBeTruthy()
})
})
27 changes: 27 additions & 0 deletions src/app/Components/ImageWithFallback/ImageWithFallback.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Box, Image, ImageProps } from "@artsy/palette-mobile"

// Extend ImageProps but make `src` optional
type ImageWithFallbackProps = Omit<ImageProps, "src"> & {
src?: string | null
}

export const ImageWithFallback: React.FC<ImageWithFallbackProps> = ({
src,
width,
height,
...props
}) => {
if (!src) {
return (
<Box
testID="fallback-image"
width={width}
height={height}
backgroundColor="black10"
borderRadius="md"
/>
)
}

return <Image testID="image" {...props} src={src} width={width} height={height} />
}
5 changes: 3 additions & 2 deletions src/app/Components/Lists/SavedItemRow.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Spacer, Flex, useColor, Text, Touchable, Image } from "@artsy/palette-mobile"
import { Spacer, Flex, useColor, Text, Touchable } from "@artsy/palette-mobile"
import { ImageWithFallback } from "app/Components/ImageWithFallback/ImageWithFallback"
import { navigate } from "app/system/navigation/navigate"

interface SavedItemRowProps {
Expand Down Expand Up @@ -36,7 +37,7 @@ export const SavedItemRow: React.FC<SavedItemRowProps> = ({
borderRadius={square_image ? 2 : size / 2}
overflow="hidden"
>
{!!imageURL && <Image src={imageURL} width={size} height={size} />}
<ImageWithFallback src={imageURL} width={size} height={size} />
</Flex>
<Spacer x={2} />
<Text variant="sm" weight="medium">
Expand Down
13 changes: 3 additions & 10 deletions src/app/Components/ShowCard.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
import {
Spacer,
Flex,
Text,
Touchable,
SkeletonBox,
SkeletonText,
Image,
} from "@artsy/palette-mobile"
import { Spacer, Flex, Text, Touchable, SkeletonBox, SkeletonText } from "@artsy/palette-mobile"
import { toTitleCase } from "@artsy/to-title-case"
import { ShowCard_show$data } from "__generated__/ShowCard_show.graphql"
import { ImageWithFallback } from "app/Components/ImageWithFallback/ImageWithFallback"
import { navigate } from "app/system/navigation/navigate"
import { compact } from "lodash"
import { GestureResponderEvent, ViewProps } from "react-native"
Expand Down Expand Up @@ -47,7 +40,7 @@ export const ShowCard: React.FC<ShowCardProps> = ({ show, onPress }) => {
<Flex width={WIDTH}>
<Touchable haptic onPress={onTap}>
<Flex width={WIDTH} overflow="hidden">
{!!imageURL && <Image src={imageURL} width={WIDTH} height={HEIGHT} />}
<ImageWithFallback src={imageURL} width={WIDTH} height={HEIGHT} />
<Spacer y={1} />
<Text numberOfLines={2} ellipsizeMode="tail" variant="sm-display" mb={0.5}>
{show.name}
Expand Down
9 changes: 5 additions & 4 deletions src/app/Components/ThreeUpImageLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Box, Image } from "@artsy/palette-mobile"
import { Box } from "@artsy/palette-mobile"
import { ImageWithFallback } from "app/Components/ImageWithFallback/ImageWithFallback"
import styled from "styled-components/native"

interface ThreeUpImageLayoutProps {
Expand All @@ -16,22 +17,22 @@ export const ThreeUpImageLayout: React.FC<ThreeUpImageLayoutProps> = ({ imageURL

return (
<ArtworkImageContainer>
<Image
<ImageWithFallback
testID="image-1"
width={LARGE_IMAGE_SIZE}
height={LARGE_IMAGE_SIZE}
src={artworkImageURLs[0]}
/>
<Division />
<Box>
<Image
<ImageWithFallback
testID="image-2"
width={SMALL_IMAGE_SIZE}
height={SMALL_IMAGE_SIZE}
src={artworkImageURLs[1]}
/>
<Division horizontal />
<Image
<ImageWithFallback
testID="image-3"
width={SMALL_IMAGE_SIZE}
height={SMALL_IMAGE_SIZE}
Expand Down
5 changes: 3 additions & 2 deletions src/app/Scenes/City/Components/TabFairItemRow/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Flex, Box, ClassTheme, Text, Image } from "@artsy/palette-mobile"
import { Flex, Box, ClassTheme, Text } from "@artsy/palette-mobile"
import { ImageWithFallback } from "app/Components/ImageWithFallback/ImageWithFallback"
import { Fair } from "app/Scenes/Map/types"
import { navigate } from "app/system/navigation/navigate"
import React from "react"
Expand All @@ -25,7 +26,7 @@ export class TabFairItemRow extends React.Component<Props> {
<TouchableWithoutFeedback onPress={() => this.handleTap(item)}>
<Flex flexWrap="nowrap" flexDirection="row" alignItems="center" mr={1}>
<RoundedImageWrapper>
{!!fairImage && <Image height={58} width={58} src={fairImage} />}
<ImageWithFallback height={58} width={58} src={fairImage} />
</RoundedImageWrapper>
<Box width={boxWidth} pl={1}>
{!!item.name && (
Expand Down
7 changes: 3 additions & 4 deletions src/app/Scenes/Feature/components/FeatureFeaturedLink.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Flex, Image, Text } from "@artsy/palette-mobile"
import { Flex, Text } from "@artsy/palette-mobile"
import { FeatureFeaturedLink_featuredLink$data } from "__generated__/FeatureFeaturedLink_featuredLink.graphql"
import { ImageWithFallback } from "app/Components/ImageWithFallback/ImageWithFallback"
import { navigate } from "app/system/navigation/navigate"
import { TouchableOpacity } from "react-native"
import LinearGradient from "react-native-linear-gradient"
Expand All @@ -22,9 +23,7 @@ const FeatureFeaturedLink: React.FC<FeatureFeaturedLinkProps> = ({ featuredLink,
}
}}
>
{!!featuredLink.image?.url && (
<Image src={featuredLink.image?.url} width={width} height={(width / 3) * 4} />
)}
<ImageWithFallback src={featuredLink.image?.url} width={width} height={(width / 3) * 4} />
<LinearGradient
colors={["rgba(0,0,0,0)", "rgba(0,0,0,0.4)"]}
style={{ position: "absolute", left: 0, right: 0, bottom: 0, height: 180 }}
Expand Down
4 changes: 2 additions & 2 deletions src/app/Scenes/GalleriesForYou/Components/PartnerListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import {
Flex,
FollowButton,
Image,
Text,
Touchable,
useScreenDimensions,
useSpace,
} from "@artsy/palette-mobile"
import { PartnerListItem_partner$key } from "__generated__/PartnerListItem_partner.graphql"
import { ImageWithFallback } from "app/Components/ImageWithFallback/ImageWithFallback"
import { sortByDistance } from "app/Scenes/GalleriesForYou/helpers"
import { navigate } from "app/system/navigation/navigate"
import { extractNodes } from "app/utils/extractNodes"
Expand Down Expand Up @@ -79,7 +79,7 @@ export const PartnerListItem: React.FC<PartnerListItemProps> = ({
<Touchable onPress={handlePress}>
<Flex width={width} mx="auto">
<Flex>
{!!imageUrl && <Image src={imageUrl} aspectRatio={1.33} width={width} />}
<ImageWithFallback src={imageUrl} aspectRatio={1.33} width={width} />

{!!showInitials && (
<Flex
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Flex, ClassTheme, Text, Touchable, Image } from "@artsy/palette-mobile"
import { Flex, ClassTheme, Text, Touchable } from "@artsy/palette-mobile"
import { themeGet } from "@styled-system/theme-get"
import { ConversationSnippet_conversation$data } from "__generated__/ConversationSnippet_conversation.graphql"
import { ImageWithFallback } from "app/Components/ImageWithFallback/ImageWithFallback"
import { Schema, Track, track as _track } from "app/utils/track"
import moment from "moment"
import React from "react"
Expand Down Expand Up @@ -28,7 +29,7 @@ const Indicator = styled.View`
background-color: ${themeGet("colors.blue100")};
`

const ImageView = styled(Image)`
const ImageView = styled(ImageWithFallback)`
border-radius: 2px;
`

Expand Down Expand Up @@ -95,9 +96,7 @@ export class ConversationSnippet extends React.Component<Props> {
<Indicator />
</Unread>
)}
{!!imageURL && (
<ImageView src={imageURL} blurhash={blurhash} width={80} height={80} />
)}
<ImageView src={imageURL} blurhash={blurhash} width={80} height={80} />
</Flex>
<Flex ml={1} style={{ flex: 1 }}>
<Flex flexDirection="row" mb="2px" style={{ flex: 0, alignItems: "center" }}>
Expand Down
12 changes: 8 additions & 4 deletions src/app/Scenes/Inbox/Components/Conversations/ItemShow.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Flex, Box, Text, Separator, Touchable, Image } from "@artsy/palette-mobile"
import { Flex, Box, Text, Separator, Touchable } from "@artsy/palette-mobile"
import { ItemShow_show$data } from "__generated__/ItemShow_show.graphql"
import { ImageWithFallback } from "app/Components/ImageWithFallback/ImageWithFallback"
import { navigate } from "app/system/navigation/navigate"
import { createFragmentContainer, graphql } from "react-relay"

Expand All @@ -18,9 +19,12 @@ export const ItemShow: React.FC<ItemShowProps> = ({ show }) => {
<Touchable onPress={() => show.href && navigate(show.href)}>
<Flex flexDirection="row">
<Box height="100px" width="100px" justifyContent="center" backgroundColor="pink">
{!!show.image?.thumbnailUrl && (
<Image testID="showImage" src={show.image?.thumbnailUrl} width={100} height={100} />
)}
<ImageWithFallback
testID="showImage"
src={show.image?.thumbnailUrl}
width={100}
height={100}
/>
</Box>
<Flex flexDirection="column" ml={2} flexShrink={1}>
<Text variant="sm" numberOfLines={1}>
Expand Down
7 changes: 3 additions & 4 deletions src/app/Scenes/MyBids/Components/Lot.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Flex, Box, Text, Image } from "@artsy/palette-mobile"
import { Flex, Box, Text } from "@artsy/palette-mobile"
import { Lot_saleArtwork$data } from "__generated__/Lot_saleArtwork.graphql"
import { ImageWithFallback } from "app/Components/ImageWithFallback/ImageWithFallback"
import React from "react"
import { createFragmentContainer, graphql } from "react-relay"

Expand All @@ -20,9 +21,7 @@ class Lot extends React.Component<Props> {
<Flex flexDirection="row" width="50%" paddingRight={2}>
<Flex mr={isSmallScreen ? 0.5 : 1}>
<Flex width={50} height={50} borderRadius={2} overflow="hidden">
{!!saleArtwork?.artwork?.image?.url && (
<Image src={saleArtwork?.artwork?.image?.url} width={50} height={50} />
)}
<ImageWithFallback src={saleArtwork?.artwork?.image?.url} width={50} height={50} />
</Flex>
{!!ArtworkBadge && (
<Box position="absolute" top={-2} left={-5}>
Expand Down
12 changes: 8 additions & 4 deletions src/app/Scenes/Partner/Components/PartnerShowRailItem.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Flex, Image, Spacer, Text, Touchable, useScreenDimensions } from "@artsy/palette-mobile"
import { Flex, Spacer, Text, Touchable, useScreenDimensions } from "@artsy/palette-mobile"
import { PartnerShowRailItem_show$data } from "__generated__/PartnerShowRailItem_show.graphql"
import { ImageWithFallback } from "app/Components/ImageWithFallback/ImageWithFallback"
import { exhibitionDates } from "app/Scenes/Map/exhibitionPeriodParser"
import { navigate } from "app/system/navigation/navigate"
import { Schema } from "app/utils/track"
Expand Down Expand Up @@ -30,9 +31,12 @@ export const PartnerShowRailItem: React.FC<Props> = (props) => {
return (
<Touchable onPress={onPress}>
<Flex my="15px" mr={2} width={sectionWidth}>
{!!imageURL && (
<Image height={200} width={sectionWidth} src={imageURL} blurhash={coverImage?.blurhash} />
)}
<ImageWithFallback
height={200}
width={sectionWidth}
src={imageURL}
blurhash={coverImage?.blurhash}
/>
<Spacer y={1} />
<Text variant="sm" numberOfLines={1}>
{name}
Expand Down
19 changes: 9 additions & 10 deletions src/app/Scenes/Search/components/SearchResultImage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Avatar, Flex, Image } from "@artsy/palette-mobile"
import { Avatar, Flex } from "@artsy/palette-mobile"
import { ImageWithFallback } from "app/Components/ImageWithFallback/ImageWithFallback"

export const IMAGE_SIZE = 40

Expand All @@ -21,15 +22,13 @@ export const SearchResultImage: React.FC<{
borderRadius={round ? IMAGE_SIZE / 2 : 0}
overflow="hidden"
>
{!!imageURL && (
<Image
testID={testID}
performResize={!(resultType === "Article")}
src={imageURL}
height={IMAGE_SIZE}
width={IMAGE_SIZE}
/>
)}
<ImageWithFallback
testID={testID}
performResize={!(resultType === "Article")}
src={imageURL}
height={IMAGE_SIZE}
width={IMAGE_SIZE}
/>
</Flex>
)
}
11 changes: 7 additions & 4 deletions src/app/Scenes/Search/components/TrendingArtistCard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Flex, Image, Text } from "@artsy/palette-mobile"
import { Flex, Text } from "@artsy/palette-mobile"
import { TrendingArtistCard_artist$key } from "__generated__/TrendingArtistCard_artist.graphql"
import { ImageWithFallback } from "app/Components/ImageWithFallback/ImageWithFallback"
import { TouchableHighlight } from "react-native"
import { useFragment, graphql } from "react-relay"

Expand All @@ -21,9 +22,11 @@ export const TrendingArtistCard: React.FC<TrendingArtistCardProps> = ({ artist,
onPress={onPress}
>
<Flex>
{!!data.coverArtwork?.image?.url && (
<Image src={data.coverArtwork?.image?.url} width={CARD_WIDTH} height={CARD_HEIGHT} />
)}
<ImageWithFallback
src={data.coverArtwork?.image?.url}
width={CARD_WIDTH}
height={CARD_HEIGHT}
/>

<Flex mt={1}>
<Text variant="xs" numberOfLines={1}>
Expand Down

0 comments on commit 1d1f97e

Please sign in to comment.