about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/state/queries/post-feed.ts7
-rw-r--r--src/view/com/posts/FeedItem.tsx117
-rw-r--r--src/view/com/posts/FeedSlice.tsx8
-rw-r--r--src/view/screens/DebugMod.tsx2
4 files changed, 78 insertions, 56 deletions
diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts
index 18c4b65a5..2851a0c2a 100644
--- a/src/state/queries/post-feed.ts
+++ b/src/state/queries/post-feed.ts
@@ -1,6 +1,7 @@
 import React, {useCallback, useEffect, useRef} from 'react'
 import {AppState} from 'react-native'
 import {
+  AppBskyActorDefs,
   AppBskyFeedDefs,
   AppBskyFeedPost,
   AtUri,
@@ -72,6 +73,7 @@ export interface FeedPostSliceItem {
   reason?: AppBskyFeedDefs.ReasonRepost | ReasonFeedSource
   feedContext: string | undefined
   moderation: ModerationDecision
+  parentAuthor?: AppBskyActorDefs.ProfileViewBasic
 }
 
 export interface FeedPostSlice {
@@ -302,6 +304,10 @@ export function usePostFeedQuery(
                           AppBskyFeedPost.validateRecord(item.post.record)
                             .success
                         ) {
+                          const parentAuthor =
+                            item.reply?.parent?.author ??
+                            slice.items[i + 1]?.reply?.grandparentAuthor
+
                           return {
                             _reactKey: `${slice._reactKey}-${i}-${item.post.uri}`,
                             uri: item.post.uri,
@@ -313,6 +319,7 @@ export function usePostFeedQuery(
                                 : item.reason,
                             feedContext: item.feedContext || slice.feedContext,
                             moderation: moderations[i],
+                            parentAuthor,
                           }
                         }
                         return undefined
diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx
index 5b4efe2af..0decb81df 100644
--- a/src/view/com/posts/FeedItem.tsx
+++ b/src/view/com/posts/FeedItem.tsx
@@ -1,6 +1,7 @@
 import React, {memo, useMemo, useState} from 'react'
 import {StyleSheet, View} from 'react-native'
 import {
+  AppBskyActorDefs,
   AppBskyFeedDefs,
   AppBskyFeedPost,
   AtUri,
@@ -40,7 +41,18 @@ import {PostEmbeds} from '../util/post-embeds'
 import {PostMeta} from '../util/PostMeta'
 import {Text} from '../util/text/Text'
 import {PreviewableUserAvatar} from '../util/UserAvatar'
-import {UserInfoText} from '../util/UserInfoText'
+
+interface FeedItemProps {
+  record: AppBskyFeedPost.Record
+  reason: AppBskyFeedDefs.ReasonRepost | ReasonFeedSource | undefined
+  moderation: ModerationDecision
+  parentAuthor: AppBskyActorDefs.ProfileViewBasic | undefined
+  showReplyTo: boolean
+  isThreadChild?: boolean
+  isThreadLastChild?: boolean
+  isThreadParent?: boolean
+  feedContext: string | undefined
+}
 
 export function FeedItem({
   post,
@@ -48,19 +60,12 @@ export function FeedItem({
   reason,
   feedContext,
   moderation,
+  parentAuthor,
+  showReplyTo,
   isThreadChild,
   isThreadLastChild,
   isThreadParent,
-}: {
-  post: AppBskyFeedDefs.PostView
-  record: AppBskyFeedPost.Record
-  reason: AppBskyFeedDefs.ReasonRepost | ReasonFeedSource | undefined
-  feedContext: string | undefined
-  moderation: ModerationDecision
-  isThreadChild?: boolean
-  isThreadLastChild?: boolean
-  isThreadParent?: boolean
-}) {
+}: FeedItemProps & {post: AppBskyFeedDefs.PostView}): React.ReactNode {
   const postShadowed = usePostShadow(post)
   const richText = useMemo(
     () =>
@@ -83,6 +88,8 @@ export function FeedItem({
         reason={reason}
         feedContext={feedContext}
         richText={richText}
+        parentAuthor={parentAuthor}
+        showReplyTo={showReplyTo}
         moderation={moderation}
         isThreadChild={isThreadChild}
         isThreadLastChild={isThreadLastChild}
@@ -100,19 +107,14 @@ let FeedItemInner = ({
   feedContext,
   richText,
   moderation,
+  parentAuthor,
+  showReplyTo,
   isThreadChild,
   isThreadLastChild,
   isThreadParent,
-}: {
-  post: Shadow<AppBskyFeedDefs.PostView>
-  record: AppBskyFeedPost.Record
-  reason: AppBskyFeedDefs.ReasonRepost | ReasonFeedSource | undefined
-  feedContext: string | undefined
+}: FeedItemProps & {
   richText: RichTextAPI
-  moderation: ModerationDecision
-  isThreadChild?: boolean
-  isThreadLastChild?: boolean
-  isThreadParent?: boolean
+  post: Shadow<AppBskyFeedDefs.PostView>
 }): React.ReactNode => {
   const queryClient = useQueryClient()
   const {openComposer} = useComposerControls()
@@ -124,14 +126,6 @@ let FeedItemInner = ({
   }, [post.uri, post.author])
   const {sendInteraction} = useFeedFeedbackContext()
 
-  const replyAuthorDid = useMemo(() => {
-    if (!record?.reply) {
-      return ''
-    }
-    const urip = new AtUri(record.reply.parent?.uri || record.reply.root.uri)
-    return urip.hostname
-  }, [record?.reply])
-
   const onPressReply = React.useCallback(() => {
     sendInteraction({
       item: post.uri,
@@ -318,34 +312,8 @@ let FeedItemInner = ({
             postHref={href}
             onOpenAuthor={onOpenAuthor}
           />
-          {!isThreadChild && replyAuthorDid !== '' && (
-            <View style={[s.flexRow, s.mb2, s.alignCenter]}>
-              <FontAwesomeIcon
-                icon="reply"
-                size={9}
-                style={[
-                  {color: pal.colors.textLight} as FontAwesomeIconStyle,
-                  s.mr5,
-                ]}
-              />
-              <Text
-                type="md"
-                style={[pal.textLight, s.mr2]}
-                lineHeight={1.2}
-                numberOfLines={1}>
-                <Trans context="description">
-                  Reply to{' '}
-                  <ProfileHoverCard inline did={replyAuthorDid}>
-                    <UserInfoText
-                      type="md"
-                      did={replyAuthorDid}
-                      attr="displayName"
-                      style={[pal.textLight]}
-                    />
-                  </ProfileHoverCard>
-                </Trans>
-              </Text>
-            </View>
+          {!isThreadChild && showReplyTo && parentAuthor && (
+            <ReplyToLabel profile={parentAuthor} />
           )}
           <LabelsOnMyPost post={post} />
           <PostContent
@@ -434,6 +402,43 @@ let PostContent = ({
 }
 PostContent = memo(PostContent)
 
+function ReplyToLabel({profile}: {profile: AppBskyActorDefs.ProfileViewBasic}) {
+  const pal = usePalette('default')
+
+  return (
+    <View style={[s.flexRow, s.mb2, s.alignCenter]}>
+      <FontAwesomeIcon
+        icon="reply"
+        size={9}
+        style={[{color: pal.colors.textLight} as FontAwesomeIconStyle, s.mr5]}
+      />
+      <Text
+        type="md"
+        style={[pal.textLight, s.mr2]}
+        lineHeight={1.2}
+        numberOfLines={1}>
+        <Trans context="description">
+          Reply to{' '}
+          <ProfileHoverCard inline did={profile.did}>
+            <TextLinkOnWebOnly
+              type="md"
+              style={pal.textLight}
+              lineHeight={1.2}
+              numberOfLines={1}
+              href={makeProfileLink(profile)}
+              text={
+                profile.displayName
+                  ? sanitizeDisplayName(profile.displayName)
+                  : sanitizeHandle(profile.handle)
+              }
+            />
+          </ProfileHoverCard>
+        </Trans>
+      </Text>
+    </View>
+  )
+}
+
 const styles = StyleSheet.create({
   outer: {
     borderTopWidth: 1,
diff --git a/src/view/com/posts/FeedSlice.tsx b/src/view/com/posts/FeedSlice.tsx
index 27a9ff8c0..6d8f038b4 100644
--- a/src/view/com/posts/FeedSlice.tsx
+++ b/src/view/com/posts/FeedSlice.tsx
@@ -22,6 +22,8 @@ let FeedSlice = ({slice}: {slice: FeedPostSlice}): React.ReactNode => {
           record={slice.items[0].record}
           reason={slice.items[0].reason}
           feedContext={slice.items[0].feedContext}
+          parentAuthor={slice.items[0].parentAuthor}
+          showReplyTo={true}
           moderation={slice.items[0].moderation}
           isThreadParent={isThreadParentAt(slice.items, 0)}
           isThreadChild={isThreadChildAt(slice.items, 0)}
@@ -32,6 +34,8 @@ let FeedSlice = ({slice}: {slice: FeedPostSlice}): React.ReactNode => {
           record={slice.items[1].record}
           reason={slice.items[1].reason}
           feedContext={slice.items[1].feedContext}
+          parentAuthor={slice.items[1].parentAuthor}
+          showReplyTo={false}
           moderation={slice.items[1].moderation}
           isThreadParent={isThreadParentAt(slice.items, 1)}
           isThreadChild={isThreadChildAt(slice.items, 1)}
@@ -43,6 +47,8 @@ let FeedSlice = ({slice}: {slice: FeedPostSlice}): React.ReactNode => {
           record={slice.items[last].record}
           reason={slice.items[last].reason}
           feedContext={slice.items[last].feedContext}
+          parentAuthor={slice.items[2].parentAuthor}
+          showReplyTo={false}
           moderation={slice.items[last].moderation}
           isThreadParent={isThreadParentAt(slice.items, last)}
           isThreadChild={isThreadChildAt(slice.items, last)}
@@ -62,6 +68,8 @@ let FeedSlice = ({slice}: {slice: FeedPostSlice}): React.ReactNode => {
           reason={slice.items[i].reason}
           feedContext={slice.items[i].feedContext}
           moderation={slice.items[i].moderation}
+          parentAuthor={slice.items[i].parentAuthor}
+          showReplyTo={i === 0}
           isThreadParent={isThreadParentAt(slice.items, i)}
           isThreadChild={isThreadChildAt(slice.items, i)}
           isThreadLastChild={
diff --git a/src/view/screens/DebugMod.tsx b/src/view/screens/DebugMod.tsx
index 86c632194..77b07b8c9 100644
--- a/src/view/screens/DebugMod.tsx
+++ b/src/view/screens/DebugMod.tsx
@@ -803,6 +803,8 @@ function MockPostFeedItem({
       post={post}
       record={post.record as AppBskyFeedPost.Record}
       moderation={moderation}
+      parentAuthor={undefined}
+      showReplyTo={false}
       reason={undefined}
       feedContext={''}
     />