diff options
Diffstat (limited to 'src/view/com/notifications/FeedItem.tsx')
-rw-r--r-- | src/view/com/notifications/FeedItem.tsx | 127 |
1 files changed, 112 insertions, 15 deletions
diff --git a/src/view/com/notifications/FeedItem.tsx b/src/view/com/notifications/FeedItem.tsx index 1eca3806f..e76056067 100644 --- a/src/view/com/notifications/FeedItem.tsx +++ b/src/view/com/notifications/FeedItem.tsx @@ -5,12 +5,14 @@ import {AdxUri} from '../../../third-party/uri' import {FontAwesomeIcon, Props} from '@fortawesome/react-native-fontawesome' import {NotificationsViewItemModel} from '../../../state/models/notifications-view' import {s, colors} from '../../lib/styles' -import {ago} from '../../lib/strings' +import {ago, pluralize} from '../../lib/strings' import {DEF_AVATER} from '../../lib/assets' import {PostText} from '../post/PostText' import {Post} from '../post/Post' import {Link} from '../util/Link' +const MAX_AUTHORS = 8 + export const FeedItem = observer(function FeedItem({ item, }: { @@ -37,39 +39,108 @@ export const FeedItem = observer(function FeedItem({ return 'Post' } }, [item]) - const authorHref = `/profile/${item.author.name}` - const authorTitle = item.author.name + + if (item.isReply) { + return ( + <Link + style={[ + styles.outerMinimal, + item.isRead ? undefined : styles.outerUnread, + ]} + href={itemHref} + title={itemTitle}> + <Post uri={item.uri} /> + </Link> + ) + } let action = '' let icon: Props['icon'] + let iconStyle: Props['style'] = [] if (item.isLike) { action = 'liked your post' - icon = ['far', 'heart'] + icon = ['fas', 'heart'] + iconStyle = [s.blue3] } else if (item.isRepost) { action = 'reposted your post' icon = 'retweet' + iconStyle = [s.blue3] } else if (item.isReply) { action = 'replied to your post' icon = ['far', 'comment'] } else if (item.isFollow) { action = 'followed you' - icon = 'plus' + icon = 'user-plus' + iconStyle = [s.blue3] } else { return <></> } + let authors: {href: string; name: string; displayName?: string}[] = [ + { + href: `/profile/${item.author.name}`, + name: item.author.name, + displayName: item.author.displayName, + }, + ] + if (item.additional?.length) { + authors = authors.concat( + item.additional.map(item2 => ({ + href: `/profile/${item2.author.name}`, + name: item2.author.name, + displayName: item2.author.displayName, + })), + ) + } + return ( - <Link style={styles.outer} href={itemHref} title={itemTitle}> + <Link + style={[styles.outer, item.isRead ? undefined : styles.outerUnread]} + href={itemHref} + title={itemTitle}> <View style={styles.layout}> - <Link style={styles.layoutAvi} href={authorHref} title={authorTitle}> - <Image style={styles.avi} source={DEF_AVATER} /> - </Link> + <View style={styles.layoutIcon}> + <FontAwesomeIcon + icon={icon} + size={22} + style={[styles.icon, ...iconStyle]} + /> + </View> <View style={styles.layoutContent}> + <View style={styles.avis}> + {authors.slice(0, MAX_AUTHORS).map(author => ( + <Link + style={s.mr2} + key={author.href} + href={author.href} + title={`@${author.name}`}> + <Image style={styles.avi} source={DEF_AVATER} /> + </Link> + ))} + {authors.length > MAX_AUTHORS ? ( + <Text style={styles.aviExtraCount}> + +{authors.length - MAX_AUTHORS} + </Text> + ) : undefined} + </View> <View style={styles.meta}> - <FontAwesomeIcon icon={icon} size={14} style={[s.mt2, s.mr5]} /> - <Link style={styles.metaItem} href={authorHref} title={authorTitle}> - <Text style={[s.f14, s.bold]}>{item.author.displayName}</Text> + <Link + key={authors[0].href} + style={styles.metaItem} + href={authors[0].href} + title={`@${authors[0].name}`}> + <Text style={[s.f14, s.bold]}> + {authors[0].displayName || authors[0].name} + </Text> </Link> + {authors.length > 1 ? ( + <> + <Text style={[styles.metaItem, s.f14]}>and</Text> + <Text style={[styles.metaItem, s.f14, s.bold]}> + {authors.length - 1} {pluralize(authors.length - 1, 'other')} + </Text> + </> + ) : undefined} <Text style={[styles.metaItem, s.f14]}>{action}</Text> <Text style={[styles.metaItem, s.f14, s.gray5]}> {ago(item.indexedAt)} @@ -97,13 +168,34 @@ const styles = StyleSheet.create({ outer: { backgroundColor: colors.white, padding: 10, - paddingBottom: 0, + borderRadius: 6, + margin: 2, + marginBottom: 0, + }, + outerMinimal: { + backgroundColor: colors.white, + borderRadius: 6, + margin: 2, + marginBottom: 0, + }, + outerUnread: { + borderWidth: 1, + borderColor: colors.blue2, }, layout: { flexDirection: 'row', }, - layoutAvi: { - width: 40, + layoutIcon: { + width: 35, + alignItems: 'flex-end', + }, + icon: { + marginRight: 10, + marginTop: 4, + }, + avis: { + flexDirection: 'row', + alignItems: 'center', }, avi: { width: 30, @@ -111,6 +203,11 @@ const styles = StyleSheet.create({ borderRadius: 15, resizeMode: 'cover', }, + aviExtraCount: { + fontWeight: 'bold', + paddingLeft: 6, + color: colors.gray5, + }, layoutContent: { flex: 1, }, |