This repository has no description
0

Configure Feed

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

semble / src / webapp / features / feeds / components / feedActivityStatus / FeedActivityStatus.tsx
2.6 kB 81 lines
1import { Anchor, Avatar, Group, Paper, Stack, Text } from '@mantine/core'; 2import { FeedItem, Collection } from '@/api-client'; 3import { Fragment } from 'react'; 4import Link from 'next/link'; 5import { getRelativeTime } from '@/lib/utils/time'; 6import { getRecordKey } from '@/lib/utils/atproto'; 7import { sanitizeText } from '@/lib/utils/text'; 8 9interface Props { 10 user: FeedItem['user']; 11 collections?: FeedItem['collections']; 12 createdAt: Date; 13} 14 15export default function FeedActivityStatus(props: Props) { 16 const MAX_DISPLAYED = 2; 17 const time = getRelativeTime(props.createdAt.toString()); 18 const relativeCreatedDate = time === 'just now' ? `Now` : `${time} ago`; 19 20 const renderActivityText = () => { 21 const collections = props.collections ?? []; 22 const displayedCollections = collections.slice(0, MAX_DISPLAYED); 23 const remainingCount = collections.length - MAX_DISPLAYED; 24 25 return ( 26 <Text fw={500} c={'gray.7'}> 27 <Anchor 28 component={Link} 29 href={`/profile/${props.user.handle}`} 30 c="blue" 31 fw={600} 32 > 33 {sanitizeText(props.user.name)} 34 </Anchor>{' '} 35 {collections.length === 0 ? ( 36 'added to library' 37 ) : ( 38 <Fragment> 39 added to{' '} 40 {displayedCollections.map( 41 (collection: Collection, index: number) => ( 42 <span key={collection.id}> 43 <Anchor 44 component={Link} 45 href={`/profile/${collection.author.handle}/collections/${getRecordKey(collection.uri!)}`} 46 c="grape" 47 fw={500} 48 > 49 {collection.name} 50 </Anchor> 51 {index < displayedCollections.length - 1 ? ', ' : ''} 52 </span> 53 ), 54 )} 55 {remainingCount > 0 && 56 ` and ${remainingCount} other collection${remainingCount > 1 ? 's' : ''}`} 57 </Fragment> 58 )} 59 <Text fz={'sm'} fw={600} c={'gray'} span display={'block'}> 60 {relativeCreatedDate} 61 </Text> 62 </Text> 63 ); 64 }; 65 66 return ( 67 <Paper bg={'gray.1'} radius={'lg'}> 68 <Stack gap={'xs'}> 69 <Group gap={'xs'} wrap="nowrap" align="center" p={'xs'}> 70 <Avatar 71 component={Link} 72 href={`/profile/${props.user.handle}`} 73 src={props.user.avatarUrl} 74 alt={`${props.user.name}'s' avatar`} 75 /> 76 {renderActivityText()} 77 </Group> 78 </Stack> 79 </Paper> 80 ); 81}