about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2023-03-21 13:36:27 -0500
committerPaul Frazee <pfrazee@gmail.com>2023-03-21 13:36:27 -0500
commit1e34e622595a2caf171b1091c98e1b40a66d44d9 (patch)
tree57bd2af78f101ffdfad2138187d7ce9ae76e0e00
parentb692f2977322d27e646d8f3872a85543b3dbc69a (diff)
downloadvoidsky-1e34e622595a2caf171b1091c98e1b40a66d44d9.tar.zst
Elide long threads in the feed (close #333)
-rw-r--r--src/state/models/feed-view.ts3
-rw-r--r--src/view/com/posts/FeedItem.tsx37
-rw-r--r--src/view/com/posts/FeedSlice.tsx83
3 files changed, 85 insertions, 38 deletions
diff --git a/src/state/models/feed-view.ts b/src/state/models/feed-view.ts
index c412065dd..0fbfa515a 100644
--- a/src/state/models/feed-view.ts
+++ b/src/state/models/feed-view.ts
@@ -200,6 +200,7 @@ export class FeedSliceModel {
   get isThread() {
     return (
       this.items.length > 1 &&
+      !this.items[0].reply &&
       this.items.every(
         item => item.post.author.did === this.items[0].post.author.did,
       )
@@ -207,7 +208,7 @@ export class FeedSliceModel {
   }
 
   get isReply() {
-    return this.items.length === 2 && !this.isThread
+    return this.items.length > 1 && !this.isThread
   }
 
   get rootItem() {
diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx
index 35a917591..573b92fd3 100644
--- a/src/view/com/posts/FeedItem.tsx
+++ b/src/view/com/posts/FeedItem.tsx
@@ -2,7 +2,6 @@ import React, {useMemo, useState} from 'react'
 import {observer} from 'mobx-react-lite'
 import {Linking, StyleSheet, View} from 'react-native'
 import Clipboard from '@react-native-clipboard/clipboard'
-import Svg, {Circle, Line} from 'react-native-svg'
 import {AtUri} from '../../../third-party/uri'
 import {
   FontAwesomeIcon,
@@ -253,32 +252,6 @@ export const FeedItem = observer(function ({
           </View>
         </View>
       </Link>
-      {false /*isThreadChildElided*/ ? (
-        <Link
-          style={[pal.view, styles.viewFullThread]}
-          href={itemHref}
-          title={itemTitle}
-          noFeedback>
-          <View style={styles.viewFullThreadDots}>
-            <Svg width="4" height="30">
-              <Line
-                x1="2"
-                y1="0"
-                x2="2"
-                y2="8"
-                stroke={pal.colors.replyLine}
-                strokeWidth="2"
-              />
-              <Circle x="2" y="14" r="1.5" fill={pal.colors.replyLineDot} />
-              <Circle x="2" y="20" r="1.5" fill={pal.colors.replyLineDot} />
-              <Circle x="2" y="26" r="1.5" fill={pal.colors.replyLineDot} />
-            </Svg>
-          </View>
-          <Text type="md" style={pal.link}>
-            View full thread
-          </Text>
-        </Link>
-      ) : undefined}
     </PostMutedWrapper>
   )
 })
@@ -348,14 +321,4 @@ const styles = StyleSheet.create({
   ctrls: {
     marginTop: 4,
   },
-  viewFullThread: {
-    paddingTop: 12,
-    paddingBottom: 2,
-    paddingLeft: 80,
-  },
-  viewFullThreadDots: {
-    position: 'absolute',
-    left: 41,
-    top: 0,
-  },
 })
diff --git a/src/view/com/posts/FeedSlice.tsx b/src/view/com/posts/FeedSlice.tsx
index 1dba8ac93..4df6d4f54 100644
--- a/src/view/com/posts/FeedSlice.tsx
+++ b/src/view/com/posts/FeedSlice.tsx
@@ -1,6 +1,12 @@
 import React from 'react'
+import {StyleSheet, View} from 'react-native'
 import {FeedSliceModel} from 'state/models/feed-view'
+import {AtUri} from '../../../third-party/uri'
+import {Link} from '../util/Link'
+import {Text} from '../util/text/Text'
+import Svg, {Circle, Line} from 'react-native-svg'
 import {FeedItem} from './FeedItem'
+import {usePalette} from 'lib/hooks/usePalette'
 
 export function FeedSlice({
   slice,
@@ -11,6 +17,39 @@ export function FeedSlice({
   showFollowBtn?: boolean
   ignoreMuteFor?: string
 }) {
+  if (slice.isThread && slice.items.length > 3) {
+    const last = slice.items.length - 1
+    return (
+      <>
+        <FeedItem
+          key={slice.items[0]._reactKey}
+          item={slice.items[0]}
+          isThreadParent={slice.isThreadParentAt(0)}
+          isThreadChild={slice.isThreadChildAt(0)}
+          showFollowBtn={showFollowBtn}
+          ignoreMuteFor={ignoreMuteFor}
+        />
+        <FeedItem
+          key={slice.items[1]._reactKey}
+          item={slice.items[1]}
+          isThreadParent={slice.isThreadParentAt(1)}
+          isThreadChild={slice.isThreadChildAt(1)}
+          showFollowBtn={showFollowBtn}
+          ignoreMuteFor={ignoreMuteFor}
+        />
+        <ViewFullThread slice={slice} />
+        <FeedItem
+          key={slice.items[last]._reactKey}
+          item={slice.items[last]}
+          isThreadParent={slice.isThreadParentAt(last)}
+          isThreadChild={slice.isThreadChildAt(last)}
+          showFollowBtn={showFollowBtn}
+          ignoreMuteFor={ignoreMuteFor}
+        />
+      </>
+    )
+  }
+
   return (
     <>
       {slice.items.map((item, i) => (
@@ -26,3 +65,47 @@ export function FeedSlice({
     </>
   )
 }
+
+function ViewFullThread({slice}: {slice: FeedSliceModel}) {
+  const pal = usePalette('default')
+  const itemHref = React.useMemo(() => {
+    const urip = new AtUri(slice.rootItem.post.uri)
+    return `/profile/${slice.rootItem.post.author.handle}/post/${urip.rkey}`
+  }, [slice.rootItem.post.uri, slice.rootItem.post.author.handle])
+
+  return (
+    <Link style={[pal.view, styles.viewFullThread]} href={itemHref} noFeedback>
+      <View style={styles.viewFullThreadDots}>
+        <Svg width="4" height="30">
+          <Line
+            x1="2"
+            y1="0"
+            x2="2"
+            y2="8"
+            stroke={pal.colors.replyLine}
+            strokeWidth="2"
+          />
+          <Circle x="2" y="16" r="1.5" fill={pal.colors.replyLineDot} />
+          <Circle x="2" y="22" r="1.5" fill={pal.colors.replyLineDot} />
+          <Circle x="2" y="28" r="1.5" fill={pal.colors.replyLineDot} />
+        </Svg>
+      </View>
+      <Text type="md" style={pal.link}>
+        View full thread
+      </Text>
+    </Link>
+  )
+}
+
+const styles = StyleSheet.create({
+  viewFullThread: {
+    paddingTop: 14,
+    paddingBottom: 6,
+    paddingLeft: 80,
+  },
+  viewFullThreadDots: {
+    position: 'absolute',
+    left: 41,
+    top: 0,
+  },
+})