about summary refs log tree commit diff
path: root/src/view/com/composer/ComposerReplyTo.tsx
diff options
context:
space:
mode:
authorEric Bailey <git@esb.lol>2025-04-18 21:15:32 -0500
committerGitHub <noreply@github.com>2025-04-18 19:15:32 -0700
commit0ac15920a477a5c8090fd2b929b36ac0b6e02c34 (patch)
treedebd067ccc0f3f5f814d8ec10082e41034d47c7c /src/view/com/composer/ComposerReplyTo.tsx
parentf1e44ee12e0ccde71e616121708e70462351f068 (diff)
downloadvoidsky-0ac15920a477a5c8090fd2b929b36ac0b6e02c34.tar.zst
Verification (#8226)
* WIP

* Alignment with icon

* Add create/remove prompts

* Fill out check dialog a bit

* Reorg

* Handle was verified state

* Add warning to edit profile

* Add warning to handle dialog

* Decent alignment in posts on all platforms

* Refactor alignment for posts, chatlist, hover card

* Disable on profile

* Convo header

* Compute simple verification state

* Add other icon, rename, integrate

* Swap in simple state for profile edits

* Clean up utility hooks

* Add verifications UI to dialog

* Add edu nux

* Revert change

* Fix wrapping of check on profile

* Rename

* Fix gap under PostMeta

* Update check dialogs

* Handle takendown verifiers in check dialog

* alf composer reply to

* Refactor verification state

* Add create/remove mutations, non-functional for now

* Fix up post-rebase

* Add check to first author noty

* Do cache updates after mutations

* DRY up hook, add to profile updates too

* Add to drawer

* Update account list

* Adapt to new types

* Hook up mutations

* Use profile shadow in feeds

* Add to settings

* Shadow currentAccountProfile

* Add invalid state to verifications

* Fix alignment and overflow in Settings and Drawer

* Re-integrate post rebase

* Remove debug code

* Update copy

* Add unverified notification support

* Remove link

* Make sure dialog closes

* Update URL

* Add settings screen

* Integrate new setting into verification states

* Add metrics, bump package, fix bad import

* NUX fixes

* Update copy

* Fixes

* Update types

* fix search autocomplete

* fix lint

* add display name warning to new dialog

* update default prefs

* Add parsing support for notifications

* Bump pkg

* Tweak noty styles

* Adjust check alignment

* Tweak check alignment

* Fix badge for verifier

* Modify copy

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
Co-authored-by: Paul Frazee <pfrazee@gmail.com>
Diffstat (limited to 'src/view/com/composer/ComposerReplyTo.tsx')
-rw-r--r--src/view/com/composer/ComposerReplyTo.tsx110
1 files changed, 56 insertions, 54 deletions
diff --git a/src/view/com/composer/ComposerReplyTo.tsx b/src/view/com/composer/ComposerReplyTo.tsx
index 2766fe625..5da530768 100644
--- a/src/view/com/composer/ComposerReplyTo.tsx
+++ b/src/view/com/composer/ComposerReplyTo.tsx
@@ -1,5 +1,5 @@
-import React from 'react'
-import {LayoutAnimation, Pressable, StyleSheet, View} from 'react-native'
+import {useCallback, useMemo, useState} from 'react'
+import {LayoutAnimation, Pressable, View} from 'react-native'
 import {Image} from 'expo-image'
 import {
   AppBskyEmbedImages,
@@ -12,20 +12,22 @@ import {useLingui} from '@lingui/react'
 
 import {sanitizeDisplayName} from '#/lib/strings/display-names'
 import {sanitizeHandle} from '#/lib/strings/handles'
-import {ComposerOptsPostRef} from '#/state/shell/composer'
+import {type ComposerOptsPostRef} from '#/state/shell/composer'
 import {MaybeQuoteEmbed} from '#/view/com/util/post-embeds/QuoteEmbed'
-import {Text} from '#/view/com/util/text/Text'
 import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar'
 import {atoms as a, useTheme} from '#/alf'
+import {Text} from '#/components/Typography'
+import {useSimpleVerificationState} from '#/components/verification'
+import {VerificationCheck} from '#/components/verification/VerificationCheck'
 
 export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) {
   const t = useTheme()
   const {_} = useLingui()
   const {embed} = replyTo
 
-  const [showFull, setShowFull] = React.useState(false)
+  const [showFull, setShowFull] = useState(false)
 
-  const onPress = React.useCallback(() => {
+  const onPress = useCallback(() => {
     setShowFull(prev => !prev)
     LayoutAnimation.configureNext({
       duration: 350,
@@ -33,7 +35,7 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) {
     })
   }, [])
 
-  const quoteEmbed = React.useMemo(() => {
+  const quoteEmbed = useMemo(() => {
     if (
       AppBskyEmbedRecord.isView(embed) &&
       AppBskyEmbedRecord.isViewRecord(embed.record) &&
@@ -50,7 +52,7 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) {
     return null
   }, [embed])
 
-  const images = React.useMemo(() => {
+  const images = useMemo(() => {
     if (AppBskyEmbedImages.isView(embed)) {
       return embed.images
     } else if (
@@ -61,17 +63,26 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) {
     }
   }, [embed])
 
+  const verification = useSimpleVerificationState({profile: replyTo.author})
+
   return (
     <Pressable
-      style={[t.atoms.border_contrast_medium, styles.replyToLayout]}
+      style={[
+        a.flex_row,
+        a.align_start,
+        a.pt_xs,
+        a.pb_lg,
+        a.mb_md,
+        a.mx_lg,
+        a.border_b,
+        t.atoms.border_contrast_medium,
+      ]}
       onPress={onPress}
       accessibilityRole="button"
       accessibilityLabel={_(
         msg`Expand or collapse the full post you are replying to`,
       )}
-      accessibilityHint={_(
-        msg`Expands or collapses the full post you are replying to`,
-      )}>
+      accessibilityHint="">
       <PreviewableUserAvatar
         size={50}
         profile={replyTo.author}
@@ -79,17 +90,30 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) {
         type={replyTo.author.associated?.labeler ? 'labeler' : 'user'}
         disableNavigation={true}
       />
-      <View style={styles.replyToPost}>
-        <Text type="xl-medium" style={t.atoms.text} numberOfLines={1} emoji>
-          {sanitizeDisplayName(
-            replyTo.author.displayName || sanitizeHandle(replyTo.author.handle),
+      <View style={[a.flex_1, a.pl_md, a.pr_sm, a.gap_2xs]}>
+        <View style={[a.flex_row, a.align_center, a.pr_xs]}>
+          <Text
+            style={[a.font_bold, a.text_md, a.flex_shrink]}
+            numberOfLines={1}
+            emoji>
+            {sanitizeDisplayName(
+              replyTo.author.displayName ||
+                sanitizeHandle(replyTo.author.handle),
+            )}
+          </Text>
+          {verification.showBadge && (
+            <View style={[a.pl_xs]}>
+              <VerificationCheck
+                width={14}
+                verifier={verification.role === 'verifier'}
+              />
+            </View>
           )}
-        </Text>
-        <View style={styles.replyToBody}>
-          <View style={styles.replyToText}>
+        </View>
+        <View style={[a.flex_row, a.gap_md]}>
+          <View style={[a.flex_1, a.flex_grow]}>
             <Text
-              type="post-text"
-              style={t.atoms.text}
+              style={[a.text_md]}
               numberOfLines={!showFull ? 6 : undefined}
               emoji>
               {replyTo.text}
@@ -112,7 +136,17 @@ function ComposerReplyToImages({
   showFull: boolean
 }) {
   return (
-    <View style={[styles.imagesContainer, a.mx_xs]}>
+    <View
+      style={[
+        a.rounded_xs,
+        a.overflow_hidden,
+        a.mt_2xs,
+        a.mx_xs,
+        {
+          height: 64,
+          width: 64,
+        },
+      ]}>
       {(images.length === 1 && (
         <Image
           source={{uri: images[0].thumb}}
@@ -196,35 +230,3 @@ function ComposerReplyToImages({
     </View>
   )
 }
-
-const styles = StyleSheet.create({
-  replyToLayout: {
-    flexDirection: 'row',
-    alignItems: 'flex-start',
-    borderBottomWidth: StyleSheet.hairlineWidth,
-    paddingTop: 4,
-    paddingBottom: 16,
-    marginBottom: 12,
-    marginHorizontal: 16,
-  },
-  replyToPost: {
-    flex: 1,
-    paddingLeft: 13,
-    paddingRight: 8,
-  },
-  replyToBody: {
-    flexDirection: 'row',
-    gap: 10,
-  },
-  replyToText: {
-    flex: 1,
-    flexGrow: 1,
-  },
-  imagesContainer: {
-    borderRadius: 6,
-    overflow: 'hidden',
-    marginTop: 2,
-    height: 64,
-    width: 64,
-  },
-})