From 4b71950d9920913a2a2cc9e493b23b87aad7cec1 Mon Sep 17 00:00:00 2001
From: dan <dan.abramov@gmail.com>
Date: Thu, 8 Aug 2024 17:05:51 +0100
Subject: Remove unnecessary state update for reply gate (#4897)

* Move mobile compose prompt to inner component

* Make canReply computed

* Use same clamp we use elsewhere
---
 src/view/com/post-thread/PostThread.tsx | 48 ++++++++++++++++++++++++---------
 1 file changed, 36 insertions(+), 12 deletions(-)

(limited to 'src/view/com/post-thread/PostThread.tsx')

diff --git a/src/view/com/post-thread/PostThread.tsx b/src/view/com/post-thread/PostThread.tsx
index b7eaedd36..401457412 100644
--- a/src/view/com/post-thread/PostThread.tsx
+++ b/src/view/com/post-thread/PostThread.tsx
@@ -1,11 +1,14 @@
-import React, {useEffect, useRef} from 'react'
-import {useWindowDimensions, View} from 'react-native'
+import React, {useRef} from 'react'
+import {StyleSheet, useWindowDimensions, View} from 'react-native'
 import {runOnJS} from 'react-native-reanimated'
+import Animated from 'react-native-reanimated'
+import {useSafeAreaInsets} from 'react-native-safe-area-context'
 import {AppBskyFeedDefs} from '@atproto/api'
 import {msg, Trans} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 
 import {moderatePost_wrapped as moderatePost} from '#/lib/moderatePost_wrapped'
+import {clamp} from '#/lib/numbers'
 import {ScrollProvider} from '#/lib/ScrollContext'
 import {isAndroid, isNative, isWeb} from '#/platform/detection'
 import {useModerationOpts} from '#/state/preferences/moderation-opts'
@@ -22,6 +25,7 @@ import {
 import {usePreferencesQuery} from '#/state/queries/preferences'
 import {useSession} from '#/state/session'
 import {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender'
+import {useMinimalShellFabTransform} from 'lib/hooks/useMinimalShellTransform'
 import {useSetTitle} from 'lib/hooks/useSetTitle'
 import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
 import {sanitizeDisplayName} from 'lib/strings/display-names'
@@ -82,11 +86,9 @@ const keyExtractor = (item: RowItem) => {
 
 export function PostThread({
   uri,
-  onCanReply,
   onPressReply,
 }: {
   uri: string | undefined
-  onCanReply: (canReply: boolean) => void
   onPressReply: () => unknown
 }) {
   const {hasSession, currentAccount} = useSession()
@@ -210,14 +212,6 @@ export function PostThread({
     return null
   }, [thread, skeleton?.highlightedPost, isThreadError, _, threadError])
 
-  useEffect(() => {
-    if (error) {
-      onCanReply(false)
-    } else if (rootPost) {
-      onCanReply(!rootPost.viewer?.replyDisabled)
-    }
-  }, [rootPost, onCanReply, error])
-
   // construct content
   const posts = React.useMemo(() => {
     if (!skeleton) return []
@@ -313,6 +307,7 @@ export function PostThread({
     setMaxReplies(prev => prev + 50)
   }, [isFetching, maxReplies, posts.length])
 
+  const canReply = !error && rootPost && !rootPost.viewer?.replyDisabled
   const hasParents =
     skeleton?.highlightedPost?.type === 'post' &&
     (skeleton.highlightedPost.ctx.isParentLoading ||
@@ -473,10 +468,30 @@ export function PostThread({
           sideBorders={false}
         />
       </ScrollProvider>
+      {isMobile && canReply && hasSession && (
+        <MobileComposePrompt onPressReply={onPressReply} />
+      )}
     </CenteredView>
   )
 }
 
+function MobileComposePrompt({onPressReply}: {onPressReply: () => unknown}) {
+  const safeAreaInsets = useSafeAreaInsets()
+  const fabMinimalShellTransform = useMinimalShellFabTransform()
+  return (
+    <Animated.View
+      style={[
+        styles.prompt,
+        fabMinimalShellTransform,
+        {
+          bottom: clamp(safeAreaInsets.bottom, 15, 30),
+        },
+      ]}>
+      <ComposePrompt onPressCompose={onPressReply} />
+    </Animated.View>
+  )
+}
+
 function isThreadPost(v: unknown): v is ThreadPost {
   return !!v && typeof v === 'object' && 'type' in v && v.type === 'post'
 }
@@ -622,3 +637,12 @@ function hasBranchingReplies(node?: ThreadNode) {
   }
   return true
 }
+
+const styles = StyleSheet.create({
+  prompt: {
+    // @ts-ignore web-only
+    position: isWeb ? 'fixed' : 'absolute',
+    left: 0,
+    right: 0,
+  },
+})
-- 
cgit 1.4.1

