This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

semble / src / webapp / features / platforms / bluesky / components / blueskyPost / BlueskyPost.tsx
2.8 kB 90 lines
1'use client'; 2 3import { AppBskyFeedDefs, AppBskyFeedPost } from '@atproto/api'; 4import { ReactElement } from 'react'; 5import { Group, Stack, Text, Avatar, Box, Image } from '@mantine/core'; 6import RichTextRenderer from '@/components/contentDisplay/richTextRenderer/RichTextRenderer'; 7import useGetBlueskyPost from '../../lib/queries/useGetBlueskyPost'; 8import PostEmbed from '../postEmbed/PostEmbed'; 9import { FaBluesky } from 'react-icons/fa6'; 10import { detectUrlPlatform, SupportedPlatform } from '@/lib/utils/link'; 11import { getPostUriFromUrl } from '@/lib/utils/atproto'; 12import BlackskyLogo from '@/assets/icons/blacksky-logo.svg'; 13import BlackskyLogoWhite from '@/assets/icons/blacksky-logo-white.svg'; 14import { useUserSettings } from '@/features/settings/lib/queries/useUserSettings'; 15 16interface Props { 17 url: string; 18 fallbackCardContent: ReactElement; 19} 20 21export default function BlueskyPost(props: Props) { 22 const { settings } = useUserSettings(); 23 const uri = getPostUriFromUrl(props.url); 24 const { data, error } = useGetBlueskyPost({ uri }); 25 const showEmbed = settings.cardView !== 'list'; 26 const platform = detectUrlPlatform(props.url); 27 const platformIcon = 28 platform.type === SupportedPlatform.BLUESKY_POST ? ( 29 <FaBluesky fill="#0085ff" size={18} /> 30 ) : ( 31 <> 32 <Image 33 src={BlackskyLogo.src} 34 alt="Blacksky logo" 35 w={18} 36 h={'auto'} 37 darkHidden 38 /> 39 <Image 40 src={BlackskyLogoWhite.src} 41 alt="Blacksky logo" 42 w={18} 43 h={'auto'} 44 lightHidden 45 /> 46 </> 47 ); 48 49 if ( 50 !data.thread || 51 !AppBskyFeedDefs.isThreadViewPost(data.thread) || 52 AppBskyFeedDefs.isNotFoundPost(data.thread.post) || 53 AppBskyFeedDefs.isBlockedPost(data.thread.post) || 54 error 55 ) { 56 return props.fallbackCardContent; 57 } 58 59 const post = data.thread.post; 60 const record = post.record as AppBskyFeedPost.Record; 61 62 return ( 63 <Stack justify="space-between" gap="xs"> 64 <Group gap="xs" justify="space-between" wrap="nowrap" w={'100%'}> 65 <Group gap={'xs'} wrap="nowrap"> 66 <Avatar 67 src={post.author.avatar?.replace('avatar', 'avatar_thumbnail')} 68 alt={`${post.author.handle} avatar`} 69 size={'sm'} 70 radius="xl" 71 /> 72 73 <Text c="bright" lineClamp={1} fw={500}> 74 {post.author.displayName || post.author.handle} 75 </Text> 76 </Group> 77 {platformIcon} 78 </Group> 79 <Stack gap={'xs'} w={'100%'}> 80 <Box> 81 <RichTextRenderer 82 text={record.text} 83 textProps={{ lineClamp: settings.cardView === 'list' ? 1 : 3 }} 84 /> 85 </Box> 86 {post.embed && showEmbed && <PostEmbed embed={post.embed} />} 87 </Stack> 88 </Stack> 89 ); 90}