2020-12-25 21:24:07 +01:00
|
|
|
import React, { useEffect, useMemo, useState } from 'react'
|
2020-10-29 14:52:28 +01:00
|
|
|
import { Image, Pressable, StyleSheet, Text, View } from 'react-native'
|
2021-01-01 16:48:16 +01:00
|
|
|
import openLink from '@components/openLink'
|
2020-12-13 14:04:25 +01:00
|
|
|
import { StyleConstants } from '@utils/styles/constants'
|
|
|
|
import { useTheme } from '@utils/styles/ThemeManager'
|
2020-12-25 21:24:07 +01:00
|
|
|
import { Surface } from 'gl-react-expo'
|
|
|
|
import { Blurhash } from 'gl-react-blurhash'
|
2020-10-29 14:52:28 +01:00
|
|
|
|
2020-10-31 21:04:46 +01:00
|
|
|
export interface Props {
|
2020-11-21 00:40:55 +01:00
|
|
|
card: Mastodon.Card
|
2020-10-31 21:04:46 +01:00
|
|
|
}
|
|
|
|
|
2020-12-03 01:28:56 +01:00
|
|
|
const TimelineCard: React.FC<Props> = ({ card }) => {
|
2020-12-01 00:44:28 +01:00
|
|
|
const { theme } = useTheme()
|
2020-11-28 17:07:30 +01:00
|
|
|
|
2020-12-26 10:39:01 +01:00
|
|
|
let isMounted = false
|
|
|
|
useEffect(() => {
|
|
|
|
isMounted = true
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
isMounted = false
|
|
|
|
}
|
|
|
|
})
|
2020-12-25 21:24:07 +01:00
|
|
|
const [imageLoaded, setImageLoaded] = useState(false)
|
2020-12-26 10:39:01 +01:00
|
|
|
useEffect(() => {
|
|
|
|
const preFetch = () =>
|
|
|
|
card.image &&
|
|
|
|
isMounted &&
|
|
|
|
Image.getSize(card.image, () => isMounted && setImageLoaded(true))
|
|
|
|
preFetch()
|
|
|
|
}, [isMounted])
|
2020-12-25 21:24:07 +01:00
|
|
|
const cardVisual = useMemo(() => {
|
|
|
|
if (imageLoaded) {
|
|
|
|
return <Image source={{ uri: card.image }} style={styles.image} />
|
|
|
|
} else {
|
2020-12-30 11:55:51 +01:00
|
|
|
return card.blurhash ? (
|
2020-12-25 21:24:07 +01:00
|
|
|
<Surface style={styles.image}>
|
|
|
|
<Blurhash hash={card.blurhash} />
|
|
|
|
</Surface>
|
2020-12-30 11:55:51 +01:00
|
|
|
) : null
|
2020-12-25 21:24:07 +01:00
|
|
|
}
|
|
|
|
}, [imageLoaded])
|
|
|
|
|
2020-10-29 14:52:28 +01:00
|
|
|
return (
|
2020-12-01 00:44:28 +01:00
|
|
|
<Pressable
|
|
|
|
style={[styles.card, { borderColor: theme.border }]}
|
2020-12-20 18:41:28 +01:00
|
|
|
onPress={async () => await openLink(card.url)}
|
2020-12-01 00:44:28 +01:00
|
|
|
>
|
2020-12-25 21:24:07 +01:00
|
|
|
{card.image && <View style={styles.left}>{cardVisual}</View>}
|
2020-11-28 17:07:30 +01:00
|
|
|
<View style={styles.right}>
|
2020-12-01 00:44:28 +01:00
|
|
|
<Text
|
|
|
|
numberOfLines={2}
|
|
|
|
style={[styles.rightTitle, { color: theme.primary }]}
|
|
|
|
>
|
|
|
|
{card.title}
|
|
|
|
</Text>
|
2020-11-28 17:07:30 +01:00
|
|
|
{card.description ? (
|
2020-12-01 00:44:28 +01:00
|
|
|
<Text
|
|
|
|
numberOfLines={1}
|
|
|
|
style={[styles.rightDescription, { color: theme.primary }]}
|
|
|
|
>
|
|
|
|
{card.description}
|
|
|
|
</Text>
|
2020-12-13 23:38:37 +01:00
|
|
|
) : null}
|
2020-12-01 00:44:28 +01:00
|
|
|
<Text numberOfLines={1} style={{ color: theme.secondary }}>
|
|
|
|
{card.url}
|
|
|
|
</Text>
|
2020-11-28 17:07:30 +01:00
|
|
|
</View>
|
|
|
|
</Pressable>
|
2020-10-29 14:52:28 +01:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
const styles = StyleSheet.create({
|
|
|
|
card: {
|
|
|
|
flex: 1,
|
|
|
|
flexDirection: 'row',
|
2020-12-01 00:44:28 +01:00
|
|
|
height: StyleConstants.Avatar.L,
|
|
|
|
marginTop: StyleConstants.Spacing.M,
|
2020-12-03 22:03:06 +01:00
|
|
|
borderWidth: StyleSheet.hairlineWidth,
|
2020-12-01 00:44:28 +01:00
|
|
|
borderRadius: 6
|
2020-10-29 14:52:28 +01:00
|
|
|
},
|
|
|
|
left: {
|
2020-12-01 00:44:28 +01:00
|
|
|
width: StyleConstants.Avatar.L
|
2020-10-29 14:52:28 +01:00
|
|
|
},
|
|
|
|
image: {
|
|
|
|
width: '100%',
|
2020-12-01 00:44:28 +01:00
|
|
|
height: '100%',
|
|
|
|
borderTopLeftRadius: 6,
|
|
|
|
borderBottomLeftRadius: 6
|
2020-10-29 14:52:28 +01:00
|
|
|
},
|
|
|
|
right: {
|
2020-12-01 00:44:28 +01:00
|
|
|
flex: 1,
|
|
|
|
padding: StyleConstants.Spacing.S
|
|
|
|
},
|
|
|
|
rightTitle: {
|
|
|
|
marginBottom: StyleConstants.Spacing.XS,
|
|
|
|
fontWeight: StyleConstants.Font.Weight.Bold
|
|
|
|
},
|
|
|
|
rightDescription: {
|
|
|
|
marginBottom: StyleConstants.Spacing.XS
|
2020-10-29 14:52:28 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2020-12-03 01:28:56 +01:00
|
|
|
export default React.memo(TimelineCard, () => true)
|