about summary refs log tree commit diff
path: root/src/view/com/notifications/FeedItem.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com/notifications/FeedItem.tsx')
-rw-r--r--src/view/com/notifications/FeedItem.tsx127
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,
   },