about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2022-11-23 14:22:40 -0600
committerPaul Frazee <pfrazee@gmail.com>2022-11-23 14:22:40 -0600
commit2b37b6549b6cb17db582a81a2bdca8316b1e4861 (patch)
tree4bbefea0af632f6f9bb537a7c78d5b045f8d916f
parenta9934998909b7d828f66e2b1b0b1e0aeb20adf6a (diff)
downloadvoidsky-2b37b6549b6cb17db582a81a2bdca8316b1e4861.tar.zst
Add replying-to context to threads
-rw-r--r--src/state/models/post-thread-view.ts34
-rw-r--r--src/view/com/post-thread/PostThreadItem.tsx57
2 files changed, 73 insertions, 18 deletions
diff --git a/src/state/models/post-thread-view.ts b/src/state/models/post-thread-view.ts
index 860a8f6ad..70e34537f 100644
--- a/src/state/models/post-thread-view.ts
+++ b/src/state/models/post-thread-view.ts
@@ -12,6 +12,17 @@ function* reactKeyGenerator(): Generator<string> {
   }
 }
 
+interface ReplyingTo {
+  author: {
+    handle: string
+    displayName?: string
+  }
+  text: string
+}
+interface OriginalRecord {
+  text: string
+}
+
 export class PostThreadViewPostMyStateModel {
   repost?: string
   upvote?: string
@@ -52,7 +63,7 @@ export class PostThreadViewPostModel implements GetPostThread.Post {
   myState = new PostThreadViewPostMyStateModel()
 
   // added data
-  replyingToAuthor?: string
+  replyingTo?: ReplyingTo
 
   constructor(
     public rootStore: RootStoreModel,
@@ -74,6 +85,7 @@ export class PostThreadViewPostModel implements GetPostThread.Post {
     v: GetPostThread.Post,
     includeParent = true,
     includeChildren = true,
+    isFirstChild = true,
   ) {
     // parents
     if (includeParent && v.parent) {
@@ -89,12 +101,19 @@ export class PostThreadViewPostModel implements GetPostThread.Post {
       }
       this.parent = parentModel
     }
-    if (v.parent?.author.handle) {
-      this.replyingToAuthor = v.parent.author.handle
+    if (!includeParent && v.parent?.author.handle && !isFirstChild) {
+      this.replyingTo = {
+        author: {
+          handle: v.parent.author.handle,
+          displayName: v.parent.author.displayName,
+        },
+        text: (v.parent.record as OriginalRecord).text,
+      }
     }
     // replies
     if (includeChildren && v.replies) {
       const replies = []
+      let isChildFirstChild = true
       for (const item of v.replies) {
         // TODO: validate .record
         const itemModel = new PostThreadViewPostModel(
@@ -104,8 +123,15 @@ export class PostThreadViewPostModel implements GetPostThread.Post {
         )
         itemModel._depth = this._depth + 1
         if (item.replies) {
-          itemModel.assignTreeModels(keyGen, item, false, true)
+          itemModel.assignTreeModels(
+            keyGen,
+            item,
+            false,
+            true,
+            isChildFirstChild,
+          )
         }
+        isChildFirstChild = false
         replies.push(itemModel)
       }
       this.replies = replies
diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx
index bb90afe19..98d6bd371 100644
--- a/src/view/com/post-thread/PostThreadItem.tsx
+++ b/src/view/com/post-thread/PostThreadItem.tsx
@@ -17,6 +17,7 @@ import {PostMeta} from '../util/PostMeta'
 import {PostCtrls} from '../util/PostCtrls'
 
 const PARENT_REPLY_LINE_LENGTH = 8
+const REPLYING_TO_LINE_LENGTH = 6
 
 export const PostThreadItem = observer(function PostThreadItem({
   item,
@@ -204,8 +205,25 @@ export const PostThreadItem = observer(function PostThreadItem({
   } else {
     return (
       <Link style={styles.outer} href={itemHref} title={itemTitle}>
-        {!!item.replyingToAuthor && <View style={styles.parentReplyLine} />}
+        {!item.replyingTo && item.record.reply && (
+          <View style={styles.parentReplyLine} />
+        )}
         {item.replies?.length !== 0 && <View style={styles.childReplyLine} />}
+        {item.replyingTo ? (
+          <View style={styles.replyingTo}>
+            <View style={styles.replyingToLine} />
+            <View style={styles.replyingToAvatar}>
+              <UserAvatar
+                handle={item.replyingTo.author.handle}
+                displayName={item.replyingTo.author.displayName}
+                size={30}
+              />
+            </View>
+            <Text style={styles.replyingToText} numberOfLines={2}>
+              {item.replyingTo.text}
+            </Text>
+          </View>
+        ) : undefined}
         <View style={styles.layout}>
           <View style={styles.layoutAvi}>
             <Link href={authorHref} title={authorTitle}>
@@ -227,19 +245,6 @@ export const PostThreadItem = observer(function PostThreadItem({
               isAuthor={item.author.did === store.me.did}
               onDeletePost={onDeletePost}
             />
-            {item.replyingToAuthor &&
-              item.replyingToAuthor !== item.author.handle && (
-                <View style={[s.flexRow, s.mb5, {alignItems: 'center'}]}>
-                  <Text style={[s.gray5, s.f15, s.mr2]}>Replying to</Text>
-                  <Link
-                    href={`/profile/${item.replyingToAuthor}`}
-                    title={`@${item.replyingToAuthor}`}>
-                    <Text style={[s.f14, s.blue3]}>
-                      @{item.replyingToAuthor}
-                    </Text>
-                  </Link>
-                </View>
-              )}
             <View style={styles.postTextContainer}>
               <RichText
                 text={record.text}
@@ -287,6 +292,30 @@ const styles = StyleSheet.create({
     borderLeftWidth: 2,
     borderLeftColor: colors.gray2,
   },
+  replyingToLine: {
+    position: 'absolute',
+    left: 34,
+    bottom: -1 * REPLYING_TO_LINE_LENGTH,
+    height: REPLYING_TO_LINE_LENGTH,
+    borderLeftWidth: 2,
+    borderLeftColor: colors.gray2,
+  },
+  replyingTo: {
+    flexDirection: 'row',
+    backgroundColor: colors.white,
+    paddingLeft: 8,
+    paddingTop: 12,
+    paddingBottom: 0,
+    paddingRight: 24,
+  },
+  replyingToAvatar: {
+    marginLeft: 12,
+    marginRight: 20,
+  },
+  replyingToText: {
+    flex: 1,
+    color: colors.gray5,
+  },
   layout: {
     flexDirection: 'row',
   },