about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSamuel Newman <mozzius@protonmail.com>2025-06-14 00:41:12 +0300
committerGitHub <noreply@github.com>2025-06-13 16:41:12 -0500
commited9691511beb26bdb799bbcb9a973a8b8df3433c (patch)
treed36687f42ed488a7079028abf3f81529887d1fd0
parent7cd607f523b715bdea4b01d9203610e764b4fbe3 (diff)
downloadvoidsky-ed9691511beb26bdb799bbcb9a973a8b8df3433c.tar.zst
Hover card on anchor displayName/handle (#8479)
* add hover to anchor display name / handle

* use newer link component

* Wrap using a single hover element

---------

Co-authored-by: Eric Bailey <git@esb.lol>
-rw-r--r--src/components/ProfileHoverCard/types.ts1
-rw-r--r--src/components/RichText.tsx10
-rw-r--r--src/screens/PostThread/components/ThreadItemAnchor.tsx85
-rw-r--r--src/view/com/post/Post.tsx2
-rw-r--r--src/view/com/posts/PostFeedItem.tsx4
-rw-r--r--src/view/com/util/PostMeta.tsx2
6 files changed, 58 insertions, 46 deletions
diff --git a/src/components/ProfileHoverCard/types.ts b/src/components/ProfileHoverCard/types.ts
index 37087dc95..01ef0fce7 100644
--- a/src/components/ProfileHoverCard/types.ts
+++ b/src/components/ProfileHoverCard/types.ts
@@ -3,6 +3,5 @@ import type React from 'react'
 export type ProfileHoverCardProps = {
   children: React.ReactElement
   did: string
-  inline?: boolean
   disable?: boolean
 }
diff --git a/src/components/RichText.tsx b/src/components/RichText.tsx
index d501f4287..6493e2342 100644
--- a/src/components/RichText.tsx
+++ b/src/components/RichText.tsx
@@ -1,14 +1,14 @@
 import React from 'react'
-import {TextStyle} from 'react-native'
+import {type TextStyle} from 'react-native'
 import {AppBskyRichtextFacet, RichText as RichTextAPI} from '@atproto/api'
 
 import {toShortUrl} from '#/lib/strings/url-helpers'
-import {atoms as a, flatten, TextStyleProp} from '#/alf'
+import {atoms as a, flatten, type TextStyleProp} from '#/alf'
 import {isOnlyEmoji} from '#/alf/typography'
-import {InlineLinkText, LinkProps} from '#/components/Link'
+import {InlineLinkText, type LinkProps} from '#/components/Link'
 import {ProfileHoverCard} from '#/components/ProfileHoverCard'
 import {RichTextTag} from '#/components/RichTextTag'
-import {Text, TextProps} from '#/components/Typography'
+import {Text, type TextProps} from '#/components/Typography'
 
 const WORD_WRAP = {wordWrap: 1}
 
@@ -105,7 +105,7 @@ export function RichText({
       !disableLinks
     ) {
       els.push(
-        <ProfileHoverCard key={key} inline did={mention.did}>
+        <ProfileHoverCard key={key} did={mention.did}>
           <InlineLinkText
             selectable={selectable}
             to={`/profile/${mention.did}`}
diff --git a/src/screens/PostThread/components/ThreadItemAnchor.tsx b/src/screens/PostThread/components/ThreadItemAnchor.tsx
index d1e3518cc..f6bc5871c 100644
--- a/src/screens/PostThread/components/ThreadItemAnchor.tsx
+++ b/src/screens/PostThread/components/ThreadItemAnchor.tsx
@@ -17,7 +17,6 @@ import {makeProfileLink} from '#/lib/routes/links'
 import {sanitizeDisplayName} from '#/lib/strings/display-names'
 import {sanitizeHandle} from '#/lib/strings/handles'
 import {niceDate} from '#/lib/strings/time'
-import {s} from '#/lib/styles'
 import {getTranslatorLink, isPostInLanguage} from '#/locale/helpers'
 import {logger} from '#/logger'
 import {
@@ -34,7 +33,6 @@ import {type OnPostSuccessData} from '#/state/shell/composer'
 import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies'
 import {type PostSource} from '#/state/unstable-post-source'
 import {PostThreadFollowBtn} from '#/view/com/post-thread/PostThreadFollowBtn'
-import {Link} from '#/view/com/util/Link'
 import {formatCount} from '#/view/com/util/numeric/format'
 import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar'
 import {
@@ -47,13 +45,14 @@ import {colors} from '#/components/Admonition'
 import {Button} from '#/components/Button'
 import {CalendarClock_Stroke2_Corner0_Rounded as CalendarClockIcon} from '#/components/icons/CalendarClock'
 import {Trash_Stroke2_Corner0_Rounded as TrashIcon} from '#/components/icons/Trash'
-import {InlineLinkText} from '#/components/Link'
+import {InlineLinkText, Link} from '#/components/Link'
 import {ContentHider} from '#/components/moderation/ContentHider'
 import {LabelsOnMyPost} from '#/components/moderation/LabelsOnMe'
 import {PostAlerts} from '#/components/moderation/PostAlerts'
 import {type AppModerationCause} from '#/components/Pills'
 import {Embed, PostEmbedViewContext} from '#/components/Post/Embed'
 import {PostControls} from '#/components/PostControls'
+import {ProfileHoverCard} from '#/components/ProfileHoverCard'
 import * as Prompt from '#/components/Prompt'
 import {RichText} from '#/components/RichText'
 import * as Skele from '#/components/Skeleton'
@@ -197,7 +196,6 @@ const ThreadItemAnchorInner = memo(function ThreadItemAnchorInner({
 
   const threadRootUri = record.reply?.root?.uri || post.uri
   const authorHref = makeProfileLink(post.author)
-  const authorTitle = post.author.handle
   const isThreadAuthor = getThreadAuthor(post, record) === currentAccount?.did
 
   const likesHref = useMemo(() => {
@@ -321,42 +319,57 @@ const ThreadItemAnchorInner = memo(function ThreadItemAnchorInner({
             live={live}
             onBeforePress={onOpenAuthor}
           />
-          <View style={[a.flex_1]}>
-            <View style={[a.flex_row, a.align_center]}>
-              <Link
-                style={[a.flex_shrink]}
-                href={authorHref}
-                title={authorTitle}
-                onBeforePress={onOpenAuthor}>
-                <Text
-                  emoji
-                  style={[a.text_lg, a.font_bold, a.leading_snug, a.self_start]}
-                  numberOfLines={1}>
-                  {sanitizeDisplayName(
+          <ProfileHoverCard did={post.author.did}>
+            <View style={[a.flex_1]}>
+              <View style={[a.flex_row, a.align_center]}>
+                <Link
+                  to={authorHref}
+                  style={[a.flex_shrink]}
+                  label={sanitizeDisplayName(
                     post.author.displayName ||
                       sanitizeHandle(post.author.handle),
                     moderation.ui('displayName'),
                   )}
-                </Text>
-              </Link>
+                  onPress={onOpenAuthor}>
+                  <Text
+                    emoji
+                    style={[
+                      a.text_lg,
+                      a.font_bold,
+                      a.leading_snug,
+                      a.self_start,
+                    ]}
+                    numberOfLines={1}>
+                    {sanitizeDisplayName(
+                      post.author.displayName ||
+                        sanitizeHandle(post.author.handle),
+                      moderation.ui('displayName'),
+                    )}
+                  </Text>
+                </Link>
 
-              <View style={[{paddingLeft: 3, top: -1}]}>
-                <VerificationCheckButton profile={authorShadow} size="md" />
+                <View style={[{paddingLeft: 3, top: -1}]}>
+                  <VerificationCheckButton profile={authorShadow} size="md" />
+                </View>
+              </View>
+              <View style={[a.align_start]}>
+                <Link
+                  style={[a.flex_shrink]}
+                  to={authorHref}
+                  label={sanitizeHandle(post.author.handle, '@')}>
+                  <Text
+                    style={[
+                      a.text_md,
+                      a.leading_snug,
+                      t.atoms.text_contrast_medium,
+                    ]}
+                    numberOfLines={1}>
+                    {sanitizeHandle(post.author.handle, '@')}
+                  </Text>
+                </Link>
               </View>
             </View>
-            <Link style={s.flex1} href={authorHref} title={authorTitle}>
-              <Text
-                emoji
-                style={[
-                  a.text_md,
-                  a.leading_snug,
-                  t.atoms.text_contrast_medium,
-                ]}
-                numberOfLines={1}>
-                {sanitizeHandle(post.author.handle, '@')}
-              </Text>
-            </Link>
-          </View>
+          </ProfileHoverCard>
           {showFollowButton && (
             <View>
               <PostThreadFollowBtn did={post.author.did} />
@@ -417,7 +430,7 @@ const ThreadItemAnchorInner = memo(function ThreadItemAnchorInner({
                 t.atoms.border_contrast_low,
               ]}>
               {post.repostCount != null && post.repostCount !== 0 ? (
-                <Link href={repostsHref} title={_(msg`Reposts of this post`)}>
+                <Link to={repostsHref} label={_(msg`Reposts of this post`)}>
                   <Text
                     testID="repostCount-expanded"
                     style={[a.text_md, t.atoms.text_contrast_medium]}>
@@ -435,7 +448,7 @@ const ThreadItemAnchorInner = memo(function ThreadItemAnchorInner({
               {post.quoteCount != null &&
               post.quoteCount !== 0 &&
               !post.viewer?.embeddingDisabled ? (
-                <Link href={quotesHref} title={_(msg`Quotes of this post`)}>
+                <Link to={quotesHref} label={_(msg`Quotes of this post`)}>
                   <Text
                     testID="quoteCount-expanded"
                     style={[a.text_md, t.atoms.text_contrast_medium]}>
@@ -451,7 +464,7 @@ const ThreadItemAnchorInner = memo(function ThreadItemAnchorInner({
                 </Link>
               ) : null}
               {post.likeCount != null && post.likeCount !== 0 ? (
-                <Link href={likesHref} title={_(msg`Likes on this post`)}>
+                <Link to={likesHref} label={_(msg`Likes on this post`)}>
                   <Text
                     testID="likeCount-expanded"
                     style={[a.text_md, t.atoms.text_contrast_medium]}>
diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx
index d92ea6a9d..19017f30f 100644
--- a/src/view/com/post/Post.tsx
+++ b/src/view/com/post/Post.tsx
@@ -204,7 +204,7 @@ function PostInner({
                 ) : (
                   <Trans context="description">
                     Reply to{' '}
-                    <ProfileHoverCard inline did={replyAuthorDid}>
+                    <ProfileHoverCard did={replyAuthorDid}>
                       <UserInfoText
                         type="sm"
                         did={replyAuthorDid}
diff --git a/src/view/com/posts/PostFeedItem.tsx b/src/view/com/posts/PostFeedItem.tsx
index a5a7a777e..6755f013d 100644
--- a/src/view/com/posts/PostFeedItem.tsx
+++ b/src/view/com/posts/PostFeedItem.tsx
@@ -368,7 +368,7 @@ let FeedItemInner = ({
                 ) : (
                   <Trans>
                     Reposted by{' '}
-                    <ProfileHoverCard inline did={reason.by.did}>
+                    <ProfileHoverCard did={reason.by.did}>
                       <TextLinkOnWebOnly
                         type="sm-bold"
                         style={pal.textLight}
@@ -607,7 +607,7 @@ function ReplyToLabel({
       label = (
         <Trans context="description">
           Reply to{' '}
-          <ProfileHoverCard inline did={profile.did}>
+          <ProfileHoverCard did={profile.did}>
             <TextLinkOnWebOnly
               type="md"
               style={pal.textLight}
diff --git a/src/view/com/util/PostMeta.tsx b/src/view/com/util/PostMeta.tsx
index 62ba32c9b..30ebbf2c2 100644
--- a/src/view/com/util/PostMeta.tsx
+++ b/src/view/com/util/PostMeta.tsx
@@ -82,7 +82,7 @@ let PostMeta = (opts: PostMetaOpts): React.ReactNode => {
         </View>
       )}
       <View style={[a.flex_row, a.align_end, a.flex_shrink]}>
-        <ProfileHoverCard inline did={author.did}>
+        <ProfileHoverCard did={author.did}>
           <View style={[a.flex_row, a.align_end, a.flex_shrink]}>
             <WebOnlyInlineLinkText
               emoji