-
Notifications
You must be signed in to change notification settings - Fork 635
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* generic card * static card * stuff * more things * stuff * ui * just committing stuff * fun * stuff * for christian * dnoe ish * overlay * img stuff * img stuff * analytics * stuff * media component * Improve FeaturedMintCard accent color contrast * lots of things * refactor * tweak * english * turn on feature flag * network badges * rename index + show chain badge for mainnet * fixes * api updates * fix account switching crash * remote config * turn off local flag * fix * flashlist -> flatlist * lang * perf * remove no data state * discover layout * fix e2e * lint * fix * fix e2e * fix sizing * recent mint gif * png * rm * disable wallet switcher android * wc: use bottom sheets on android * tab bar color * avatar fix --------- Co-authored-by: Christian Baroni <[email protected]> Co-authored-by: skylarbarrera <[email protected]>
- Loading branch information
1 parent
a15ccb2
commit f04ddc0
Showing
28 changed files
with
2,013 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import React, { useState } from 'react'; | ||
import { maybeSignUri } from '@/handlers/imgix'; | ||
import { Image, ImageStyle, View } from 'react-native'; | ||
// @ts-ignore | ||
import Video from 'react-native-video'; | ||
import SvgImage from './svg/SvgImage'; | ||
|
||
export enum MimeType { | ||
MP4 = 'video/mp4', | ||
GIF = 'image/gif', | ||
PNG = 'image/png', | ||
SVG = 'image/svg+xml', | ||
JPG = 'image/jpeg', | ||
} | ||
|
||
export function Media({ | ||
url, | ||
mimeType, | ||
fallbackUrl, | ||
style, | ||
size, | ||
onLayout, | ||
onError, | ||
}: { | ||
url: string; | ||
mimeType?: string; | ||
fallbackUrl?: string; | ||
style?: ImageStyle; | ||
size?: number; | ||
onLayout?: () => void; | ||
onError?: () => void; | ||
}) { | ||
const [loading, setLoading] = useState(false); | ||
|
||
const signedUrl = maybeSignUri(url, { | ||
// resizing breaks svg | ||
w: mimeType === MimeType.SVG ? undefined : size, | ||
fm: !mimeType ? 'png' : undefined, | ||
}); | ||
const signedFallbackUrl = maybeSignUri(fallbackUrl ?? url, { | ||
w: size, | ||
fm: 'png', | ||
}); | ||
|
||
switch (mimeType) { | ||
case MimeType.MP4: | ||
return ( | ||
<Video | ||
onLayout={onLayout} | ||
loading={loading} | ||
onError={onError} | ||
muted | ||
resizeMode="cover" | ||
poster={signedFallbackUrl} | ||
posterResizeMode="cover" | ||
setLoading={setLoading} | ||
repeat | ||
style={style} | ||
source={{ uri: signedUrl }} | ||
uri={signedUrl} | ||
/> | ||
); | ||
case MimeType.SVG: | ||
return ( | ||
<View style={{ ...style, overflow: 'hidden' }}> | ||
<SvgImage | ||
fallbackUri={signedFallbackUrl} | ||
onLayout={onLayout} | ||
onError={onError} | ||
style={style} | ||
source={{ uri: signedUrl }} | ||
/> | ||
</View> | ||
); | ||
case MimeType.GIF: | ||
case MimeType.PNG: | ||
case MimeType.JPG: | ||
default: | ||
return ( | ||
<Image | ||
onLayout={onLayout} | ||
onError={onError} | ||
source={{ uri: signedUrl }} | ||
style={style} | ||
/> | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
import { | ||
Bleed, | ||
Box, | ||
Column, | ||
Columns, | ||
Inline, | ||
Stack, | ||
Text, | ||
useColorMode, | ||
useForegroundColor, | ||
} from '@/design-system'; | ||
import React from 'react'; | ||
import { FlashList, ListRenderItem } from '@shopify/flash-list'; | ||
import { ButtonPressAnimation } from '@/components/animations'; | ||
import { useDimensions } from '@/hooks'; | ||
import ActivityIndicator from '@/components/ActivityIndicator'; | ||
import { IS_ANDROID } from '@/env'; | ||
import Spinner from '@/components/Spinner'; | ||
import { ScrollView, View } from 'react-native'; | ||
|
||
const HORIZONTAL_PADDING = 20; | ||
|
||
const LoadingSpinner = IS_ANDROID ? Spinner : ActivityIndicator; | ||
|
||
type CarouselItem<T> = { | ||
renderItem: ListRenderItem<T>; | ||
keyExtractor: (item: T, index: number) => string; | ||
placeholder: React.ReactNode; | ||
width: number; | ||
height: number; // make sure to include extra 20px to accommodate for vertical bleed | ||
padding: number; | ||
verticalOverflow?: number; | ||
}; | ||
|
||
export function CarouselCard<T>({ | ||
title, | ||
data, | ||
carouselItem, | ||
button, | ||
menu, | ||
refresh, | ||
canRefresh, | ||
isRefreshing, | ||
}: { | ||
title: string | React.ReactNode; | ||
data: T[] | null | undefined; | ||
carouselItem: CarouselItem<T>; | ||
button: React.ReactNode; | ||
menu?: React.ReactNode; | ||
refresh?: () => void; | ||
canRefresh?: boolean; | ||
isRefreshing?: boolean; | ||
}) { | ||
const borderColor = useForegroundColor('separator'); | ||
const { width: deviceWidth } = useDimensions(); | ||
const { colorMode } = useColorMode(); | ||
|
||
const actualItemHeight = | ||
carouselItem.height + (carouselItem.verticalOverflow ?? 0) * 2; | ||
|
||
return ( | ||
<Stack space="20px"> | ||
<Box | ||
flexDirection="row" | ||
alignItems="center" | ||
justifyContent="space-between" | ||
> | ||
{typeof title === 'string' ? ( | ||
<Text color="label" weight="heavy" size="20pt"> | ||
{title} | ||
</Text> | ||
) : ( | ||
<Box width="full">{title}</Box> | ||
)} | ||
{menu} | ||
</Box> | ||
{/* FlashList vertical visible overflow does not work due to a bug, | ||
so we need to manually add vertical padding to the recycled component. | ||
The vertical bleed here is to accommodate the vertical padding w/o affecting the layout. | ||
See https://github.com/Shopify/flash-list/issues/723*/} | ||
<Bleed | ||
horizontal="20px" | ||
vertical={{ custom: carouselItem.verticalOverflow ?? 0 }} | ||
> | ||
<Box height={{ custom: actualItemHeight }}> | ||
{data?.length ? ( | ||
<FlashList | ||
data={data} | ||
showsHorizontalScrollIndicator={false} | ||
contentContainerStyle={{ | ||
paddingHorizontal: HORIZONTAL_PADDING, | ||
}} | ||
estimatedItemSize={carouselItem.width} | ||
horizontal | ||
estimatedListSize={{ | ||
height: actualItemHeight, | ||
width: deviceWidth * 2, | ||
}} | ||
style={{ flex: 1 }} | ||
renderItem={info => ( | ||
<View | ||
style={{ | ||
paddingVertical: carouselItem.verticalOverflow, | ||
alignItems: 'center', | ||
}} | ||
> | ||
{carouselItem.renderItem(info)} | ||
</View> | ||
)} | ||
ItemSeparatorComponent={() => ( | ||
<View style={{ width: carouselItem.padding }} /> | ||
)} | ||
keyExtractor={carouselItem.keyExtractor} | ||
/> | ||
) : ( | ||
// need this due to FlashList bug https://github.com/Shopify/flash-list/issues/757 | ||
<ScrollView | ||
horizontal | ||
showsHorizontalScrollIndicator={false} | ||
contentContainerStyle={{ | ||
paddingHorizontal: HORIZONTAL_PADDING, | ||
}} | ||
> | ||
<Inline space={{ custom: carouselItem.padding }}> | ||
{carouselItem.placeholder} | ||
{carouselItem.placeholder} | ||
{carouselItem.placeholder} | ||
{carouselItem.placeholder} | ||
{carouselItem.placeholder} | ||
</Inline> | ||
</ScrollView> | ||
)} | ||
</Box> | ||
</Bleed> | ||
<Columns space="10px"> | ||
<Column>{button}</Column> | ||
{!!refresh && ( | ||
<Column width="content"> | ||
<Box | ||
as={ButtonPressAnimation} | ||
// @ts-ignore | ||
disabled={!canRefresh} | ||
onPress={refresh} | ||
justifyContent="center" | ||
alignItems="center" | ||
borderRadius={18} | ||
style={{ | ||
borderWidth: isRefreshing ? 0 : 1, | ||
borderColor, | ||
width: 36, | ||
height: 36, | ||
}} | ||
> | ||
{isRefreshing ? ( | ||
<LoadingSpinner | ||
color={colorMode === 'light' ? 'black' : 'white'} | ||
size={20} | ||
/> | ||
) : ( | ||
<Text align="center" color="label" size="17pt" weight="bold"> | ||
| ||
</Text> | ||
)} | ||
</Box> | ||
</Column> | ||
)} | ||
</Columns> | ||
</Stack> | ||
); | ||
} |
Oops, something went wrong.