[APP-2160] Add PublicationEmbed card component

This commit is contained in:
vineyardbovines
2026-05-12 13:02:15 -04:00
committed by Eric Bailey
parent 9ef53e3912
commit 3d11904294
@@ -0,0 +1,115 @@
import {type StyleProp, View, type ViewStyle} from 'react-native'
import {Image} from 'expo-image'
import {useLingui} from '@lingui/react/macro'
import {useHaptics} from '#/lib/haptics'
import {shareUrl} from '#/lib/sharing'
import {atoms as a, useTheme} from '#/alf'
import {Divider} from '#/components/Divider'
import {Link} from '#/components/Link'
import {Text} from '#/components/Typography'
import {IS_NATIVE} from '#/env'
import {MetaRow} from './MetaRow'
import {PublicationFooter} from './PublicationFooter'
import {
type PublicationViewExternal,
type PublicationViewExternalSource,
} from './types'
export function PublicationEmbed({
link,
source,
onOpen,
style,
}: {
link: PublicationViewExternal
source: PublicationViewExternalSource
onOpen?: () => void
style?: StyleProp<ViewStyle>
}) {
const t = useTheme()
const {t: l} = useLingui()
const playHaptic = useHaptics()
const onPress = () => {
playHaptic('Light')
onOpen?.()
}
const onShareExternal = () => {
if (link.uri && IS_NATIVE) {
playHaptic('Heavy')
shareUrl(link.uri)
}
}
return (
<View
testID="publication-embed"
style={[
a.w_full,
a.rounded_md,
a.overflow_hidden,
a.border,
t.atoms.border_contrast_low,
style,
]}>
<Link
to={link.uri}
label={link.title || l`Open link to ${link.uri}`}
shouldProxy
onPress={onPress}
onLongPress={onShareExternal}>
{({hovered}) => (
<View
style={[
a.flex_col,
a.transition_color,
hovered ? t.atoms.bg_contrast_25 : null,
]}>
{link.thumb ? (
<Image
style={[a.aspect_card]}
source={{uri: link.thumb}}
accessibilityIgnoresInvertColors
loading="lazy"
/>
) : null}
<View style={[a.p_md, a.gap_sm]}>
<View style={[{gap: 4}]}>
<Text
emoji
numberOfLines={3}
style={[
a.text_md,
a.font_semi_bold,
a.leading_snug,
t.atoms.text,
]}>
{link.title || link.uri}
</Text>
{link.description ? (
<Text
emoji
numberOfLines={2}
style={[a.text_xs, a.leading_snug, t.atoms.text]}>
{link.description}
</Text>
) : null}
</View>
<MetaRow link={link} />
</View>
</View>
)}
</Link>
<Divider />
<PublicationFooter source={source} />
{/*
Note: `source.theme` (background/foreground/accent/accentForeground
RGB triplets) is exposed by the lexicon but not consumed here. The
current design does not apply per-publication accent colors. Pick up
when product asks for theme accenting.
*/}
</View>
)
}