From 4515559b1a7db493188cfe92abf8ea5cfd53c6dc Mon Sep 17 00:00:00 2001
From: Eric Bailey <git@esb.lol>
Date: Wed, 19 Jul 2023 12:08:40 -0500
Subject: [PATCH] #929 Wrap `PasteInput` updates in a `setTimeout` (#1033)

* wrap PasteInput updates in a setTimeout

* just wrap the whole callback
---
 .../com/composer/text-input/TextInput.tsx     | 84 +++++++++++--------
 1 file changed, 48 insertions(+), 36 deletions(-)

diff --git a/src/view/com/composer/text-input/TextInput.tsx b/src/view/com/composer/text-input/TextInput.tsx
index 08da42ab..32fdb4aa 100644
--- a/src/view/com/composer/text-input/TextInput.tsx
+++ b/src/view/com/composer/text-input/TextInput.tsx
@@ -79,52 +79,64 @@ export const TextInput = forwardRef(
     }))
 
     const onChangeText = useCallback(
-      async (newText: string) => {
-        const newRt = new RichText({text: newText})
-        newRt.detectFacetsWithoutResolution()
-        setRichText(newRt)
+      (newText: string) => {
+        /*
+         * This is a hack to bump the rendering of our styled
+         * `textDecorated` to _after_ whatever processing is happening
+         * within the `PasteInput` library. Without this, the elements in
+         * `textDecorated` are not correctly painted to screen.
+         *
+         * NB: we tried a `0` timeout as well, but only positive values worked.
+         *
+         * @see https://github.com/bluesky-social/social-app/issues/929
+         */
+        setTimeout(async () => {
+          const newRt = new RichText({text: newText})
+          newRt.detectFacetsWithoutResolution()
+          setRichText(newRt)
 
-        const prefix = getMentionAt(
-          newText,
-          textInputSelection.current?.start || 0,
-        )
-        if (prefix) {
-          autocompleteView.setActive(true)
-          autocompleteView.setPrefix(prefix.value)
-        } else {
-          autocompleteView.setActive(false)
-        }
+          const prefix = getMentionAt(
+            newText,
+            textInputSelection.current?.start || 0,
+          )
+          if (prefix) {
+            autocompleteView.setActive(true)
+            autocompleteView.setPrefix(prefix.value)
+          } else {
+            autocompleteView.setActive(false)
+          }
 
-        const set: Set<string> = new Set()
+          const set: Set<string> = new Set()
 
-        if (newRt.facets) {
-          for (const facet of newRt.facets) {
-            for (const feature of facet.features) {
-              if (AppBskyRichtextFacet.isLink(feature)) {
-                if (isUriImage(feature.uri)) {
-                  const res = await downloadAndResize({
-                    uri: feature.uri,
-                    width: POST_IMG_MAX.width,
-                    height: POST_IMG_MAX.height,
-                    mode: 'contain',
-                    maxSize: POST_IMG_MAX.size,
-                    timeout: 15e3,
-                  })
+          if (newRt.facets) {
+            for (const facet of newRt.facets) {
+              for (const feature of facet.features) {
+                if (AppBskyRichtextFacet.isLink(feature)) {
+                  if (isUriImage(feature.uri)) {
+                    const res = await downloadAndResize({
+                      uri: feature.uri,
+                      width: POST_IMG_MAX.width,
+                      height: POST_IMG_MAX.height,
+                      mode: 'contain',
+                      maxSize: POST_IMG_MAX.size,
+                      timeout: 15e3,
+                    })
 
-                  if (res !== undefined) {
-                    onPhotoPasted(res.path)
+                    if (res !== undefined) {
+                      onPhotoPasted(res.path)
+                    }
+                  } else {
+                    set.add(feature.uri)
                   }
-                } else {
-                  set.add(feature.uri)
                 }
               }
             }
           }
-        }
 
-        if (!isEqual(set, suggestedLinks)) {
-          onSuggestedLinksChanged(set)
-        }
+          if (!isEqual(set, suggestedLinks)) {
+            onSuggestedLinksChanged(set)
+          }
+        }, 1)
       },
       [
         setRichText,