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