mirror of
https://github.com/hanzo-io/team.git
synced 2026-10-30 18:56:23 +00:00
77 lines
2.8 KiB
TypeScript
77 lines
2.8 KiB
TypeScript
import Skeleton from '@components/layout/Skeleton';
|
|
import { useLinkPreview } from '@hooks/useLinkPreview';
|
|
import { memo } from 'react';
|
|
import { View, Text, TouchableOpacity, Linking } from 'react-native';
|
|
import { Image } from 'expo-image';
|
|
|
|
type LinkPreviewProps = {
|
|
messageID: string;
|
|
href: string;
|
|
};
|
|
|
|
const LinkPreview = memo(({ href }: LinkPreviewProps) => {
|
|
|
|
const { linkPreview, isLoading } = useLinkPreview(href);
|
|
|
|
const handleLinkPress = async () => {
|
|
if (href) {
|
|
const canOpen = await Linking.canOpenURL(href);
|
|
if (canOpen) {
|
|
await Linking.openURL(href);
|
|
}
|
|
}
|
|
};
|
|
|
|
if (isLoading) return <LinkPreviewSkeleton />
|
|
|
|
if (!href || !linkPreview) return null;
|
|
|
|
const image = linkPreview.absolute_image || linkPreview.image;
|
|
|
|
if (!image && !linkPreview.title && !linkPreview.description) return null;
|
|
|
|
return (
|
|
<View className="w-full border border-border bg-card-background/40 rounded-lg overflow-hidden relative">
|
|
<TouchableOpacity onPress={handleLinkPress} activeOpacity={0.7}>
|
|
<View>
|
|
{image && <Image
|
|
source={{ uri: image }}
|
|
contentFit="cover"
|
|
contentPosition={'center'}
|
|
style={{ width: '100%', height: 144 }}
|
|
/>}
|
|
<View className="p-2 pt-2.5">
|
|
<View className='gap-1'>
|
|
<Text className="text-md text-foreground font-bold" numberOfLines={1}>
|
|
{linkPreview.title}
|
|
</Text>
|
|
<Text className="text-sm text-muted-foreground">
|
|
{linkPreview.site_name}
|
|
</Text>
|
|
</View>
|
|
<Text className="text-xs text-muted-foreground pt-1.5 text-ellipsis" numberOfLines={2}>
|
|
{linkPreview.description}
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
</TouchableOpacity>
|
|
</View>
|
|
);
|
|
});
|
|
|
|
const LinkPreviewSkeleton = () => {
|
|
return <View className='w-full border border-border bg-card-background/40 rounded-lg overflow-hidden relative'>
|
|
<Skeleton className='h-36 w-full' />
|
|
<View className='w-full p-2 pt-2.5'>
|
|
<View className='gap-2'>
|
|
<Skeleton className='h-4 w-3/4' />
|
|
<Skeleton className='h-3 w-1/3' />
|
|
</View>
|
|
<View className='gap-1.5 pt-2'>
|
|
<Skeleton className='h-3 w-full' />
|
|
<Skeleton className='h-3 w-3/4' />
|
|
</View>
|
|
</View>
|
|
</View>
|
|
}
|
|
export default LinkPreview; |