2021-01-16 00:00:31 +01:00
|
|
|
import { StyleConstants } from '@utils/styles/constants'
|
2021-01-28 01:14:00 +01:00
|
|
|
import React, { useCallback, useState } from 'react'
|
2021-01-16 00:00:31 +01:00
|
|
|
import {
|
2021-01-23 02:41:50 +01:00
|
|
|
ImageStyle,
|
2021-01-16 00:00:31 +01:00
|
|
|
Pressable,
|
|
|
|
StyleProp,
|
|
|
|
StyleSheet,
|
|
|
|
ViewStyle
|
|
|
|
} from 'react-native'
|
2021-01-28 01:31:19 +01:00
|
|
|
import { Blurhash } from 'react-native-blurhash'
|
2021-01-28 01:14:00 +01:00
|
|
|
import FastImage from 'react-native-fast-image'
|
2021-01-16 00:00:31 +01:00
|
|
|
import { useTheme } from '@utils/styles/ThemeManager'
|
|
|
|
|
|
|
|
export interface Props {
|
|
|
|
hidden?: boolean
|
2021-01-28 01:14:00 +01:00
|
|
|
uri: { preview?: string; original: string; remote?: string }
|
2021-01-16 00:00:31 +01:00
|
|
|
blurhash?: string
|
|
|
|
dimension?: { width: number; height: number }
|
|
|
|
onPress?: () => void
|
|
|
|
style?: StyleProp<ViewStyle>
|
2021-01-23 02:41:50 +01:00
|
|
|
imageStyle?: StyleProp<ImageStyle>
|
2021-01-16 00:00:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
const GracefullyImage: React.FC<Props> = ({
|
|
|
|
hidden = false,
|
|
|
|
uri,
|
|
|
|
blurhash,
|
|
|
|
dimension,
|
|
|
|
onPress,
|
2021-01-23 02:41:50 +01:00
|
|
|
style,
|
|
|
|
imageStyle
|
2021-01-16 00:00:31 +01:00
|
|
|
}) => {
|
|
|
|
const { mode, theme } = useTheme()
|
2021-01-28 01:14:00 +01:00
|
|
|
const [imageLoaded, setImageLoaded] = useState(false)
|
2021-01-16 00:00:31 +01:00
|
|
|
|
|
|
|
const children = useCallback(() => {
|
2021-01-28 01:14:00 +01:00
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<FastImage
|
|
|
|
source={{ uri: uri.preview || uri.original || uri.remote }}
|
|
|
|
style={[styles.image, imageStyle]}
|
|
|
|
onLoad={() => setImageLoaded(true)}
|
|
|
|
/>
|
|
|
|
{blurhash && (hidden || !imageLoaded) ? (
|
2021-01-28 01:31:19 +01:00
|
|
|
<Blurhash
|
|
|
|
decodeAsync
|
|
|
|
blurhash={blurhash}
|
2021-01-28 01:14:00 +01:00
|
|
|
style={{
|
|
|
|
width: '100%',
|
|
|
|
height: '100%',
|
|
|
|
position: 'absolute',
|
|
|
|
top: StyleConstants.Spacing.XS / 2,
|
|
|
|
left: StyleConstants.Spacing.XS / 2
|
|
|
|
}}
|
2021-01-28 01:31:19 +01:00
|
|
|
/>
|
2021-01-28 01:14:00 +01:00
|
|
|
) : null}
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
}, [hidden, imageLoaded, mode, uri])
|
2021-01-16 00:00:31 +01:00
|
|
|
|
|
|
|
return (
|
|
|
|
<Pressable
|
|
|
|
children={children}
|
2021-01-23 02:41:50 +01:00
|
|
|
style={[
|
|
|
|
style,
|
|
|
|
{ backgroundColor: theme.shimmerDefault },
|
|
|
|
dimension && { ...dimension }
|
|
|
|
]}
|
2021-01-16 00:00:31 +01:00
|
|
|
{...(onPress
|
2021-01-17 22:37:05 +01:00
|
|
|
? hidden
|
2021-01-16 00:00:31 +01:00
|
|
|
? { disabled: true }
|
|
|
|
: { onPress }
|
|
|
|
: { disabled: true })}
|
|
|
|
/>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
const styles = StyleSheet.create({
|
|
|
|
image: {
|
|
|
|
flex: 1
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
export default GracefullyImage
|