import React, { useEffect, useMemo, useState } from 'react' import { Image, Pressable, StyleSheet, Text, View } from 'react-native' import openLink from '@components/openLink' import { StyleConstants } from '@utils/styles/constants' import { useTheme } from '@utils/styles/ThemeManager' import { Surface } from 'gl-react-expo' import { Blurhash } from 'gl-react-blurhash' export interface Props { card: Mastodon.Card } const TimelineCard: React.FC = ({ card }) => { const { theme } = useTheme() let isMounted = false useEffect(() => { isMounted = true return () => { isMounted = false } }) const [imageLoaded, setImageLoaded] = useState(false) useEffect(() => { const preFetch = () => card.image && isMounted && Image.getSize(card.image, () => isMounted && setImageLoaded(true)) preFetch() }, [isMounted]) const cardVisual = useMemo(() => { if (imageLoaded) { return } else { return card.blurhash ? ( ) : null } }, [imageLoaded]) return ( await openLink(card.url)} > {card.image && {cardVisual}} {card.title} {card.description ? ( {card.description} ) : null} {card.url} ) } const styles = StyleSheet.create({ card: { flex: 1, flexDirection: 'row', height: StyleConstants.Avatar.L, marginTop: StyleConstants.Spacing.M, borderWidth: StyleSheet.hairlineWidth, borderRadius: 6 }, left: { width: StyleConstants.Avatar.L }, image: { width: '100%', height: '100%', borderTopLeftRadius: 6, borderBottomLeftRadius: 6 }, right: { flex: 1, padding: StyleConstants.Spacing.S }, rightTitle: { marginBottom: StyleConstants.Spacing.XS, fontWeight: StyleConstants.Font.Weight.Bold }, rightDescription: { marginBottom: StyleConstants.Spacing.XS } }) export default React.memo(TimelineCard, () => true)