about summary refs log tree commit diff
path: root/src/view/com/composer/text-input/TextInput.web.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com/composer/text-input/TextInput.web.tsx')
-rw-r--r--src/view/com/composer/text-input/TextInput.web.tsx219
1 files changed, 107 insertions, 112 deletions
diff --git a/src/view/com/composer/text-input/TextInput.web.tsx b/src/view/com/composer/text-input/TextInput.web.tsx
index 77f634930..e90298817 100644
--- a/src/view/com/composer/text-input/TextInput.web.tsx
+++ b/src/view/com/composer/text-input/TextInput.web.tsx
@@ -37,135 +37,130 @@ interface TextInputProps {
 
 export const textInputWebEmitter = new EventEmitter()
 
-export const TextInput = React.forwardRef(
-  (
-    {
-      richtext,
-      placeholder,
-      suggestedLinks,
-      autocompleteView,
-      setRichText,
-      onPhotoPasted,
-      onPressPublish,
-      onSuggestedLinksChanged,
-    }: // onError, TODO
-    TextInputProps,
-    ref,
-  ) => {
-    const modeClass = useColorSchemeStyle(
-      'ProseMirror-light',
-      'ProseMirror-dark',
-    )
+export const TextInput = React.forwardRef(function TextInputImpl(
+  {
+    richtext,
+    placeholder,
+    suggestedLinks,
+    autocompleteView,
+    setRichText,
+    onPhotoPasted,
+    onPressPublish,
+    onSuggestedLinksChanged,
+  }: // onError, TODO
+  TextInputProps,
+  ref,
+) {
+  const modeClass = useColorSchemeStyle('ProseMirror-light', 'ProseMirror-dark')
 
-    React.useEffect(() => {
-      textInputWebEmitter.addListener('publish', onPressPublish)
-      return () => {
-        textInputWebEmitter.removeListener('publish', onPressPublish)
-      }
-    }, [onPressPublish])
-    React.useEffect(() => {
-      textInputWebEmitter.addListener('photo-pasted', onPhotoPasted)
-      return () => {
-        textInputWebEmitter.removeListener('photo-pasted', onPhotoPasted)
-      }
-    }, [onPhotoPasted])
+  React.useEffect(() => {
+    textInputWebEmitter.addListener('publish', onPressPublish)
+    return () => {
+      textInputWebEmitter.removeListener('publish', onPressPublish)
+    }
+  }, [onPressPublish])
+  React.useEffect(() => {
+    textInputWebEmitter.addListener('photo-pasted', onPhotoPasted)
+    return () => {
+      textInputWebEmitter.removeListener('photo-pasted', onPhotoPasted)
+    }
+  }, [onPhotoPasted])
 
-    const editor = useEditor(
-      {
-        extensions: [
-          Document,
-          LinkDecorator,
-          Mention.configure({
-            HTMLAttributes: {
-              class: 'mention',
-            },
-            suggestion: createSuggestion({autocompleteView}),
-          }),
-          Paragraph,
-          Placeholder.configure({
-            placeholder,
-          }),
-          Text,
-          History,
-          Hardbreak,
-        ],
-        editorProps: {
-          attributes: {
-            class: modeClass,
+  const editor = useEditor(
+    {
+      extensions: [
+        Document,
+        LinkDecorator,
+        Mention.configure({
+          HTMLAttributes: {
+            class: 'mention',
           },
-          handlePaste: (_, event) => {
-            const items = event.clipboardData?.items
+          suggestion: createSuggestion({autocompleteView}),
+        }),
+        Paragraph,
+        Placeholder.configure({
+          placeholder,
+        }),
+        Text,
+        History,
+        Hardbreak,
+      ],
+      editorProps: {
+        attributes: {
+          class: modeClass,
+        },
+        handlePaste: (_, event) => {
+          const items = event.clipboardData?.items
 
-            if (items === undefined) {
-              return
-            }
+          if (items === undefined) {
+            return
+          }
 
-            getImageFromUri(items, (uri: string) => {
-              textInputWebEmitter.emit('photo-pasted', uri)
-            })
-          },
-          handleKeyDown: (_, event) => {
-            if ((event.metaKey || event.ctrlKey) && event.code === 'Enter') {
-              textInputWebEmitter.emit('publish')
-            }
-          },
+          getImageFromUri(items, (uri: string) => {
+            textInputWebEmitter.emit('photo-pasted', uri)
+          })
         },
-        content: textToEditorJson(richtext.text.toString()),
-        autofocus: 'end',
-        editable: true,
-        injectCSS: true,
-        onUpdate({editor: editorProp}) {
-          const json = editorProp.getJSON()
+        handleKeyDown: (_, event) => {
+          if ((event.metaKey || event.ctrlKey) && event.code === 'Enter') {
+            textInputWebEmitter.emit('publish')
+          }
+        },
+      },
+      content: textToEditorJson(richtext.text.toString()),
+      autofocus: 'end',
+      editable: true,
+      injectCSS: true,
+      onUpdate({editor: editorProp}) {
+        const json = editorProp.getJSON()
 
-          const newRt = new RichText({text: editorJsonToText(json).trim()})
-          newRt.detectFacetsWithoutResolution()
-          setRichText(newRt)
+        const newRt = new RichText({text: editorJsonToText(json).trim()})
+        newRt.detectFacetsWithoutResolution()
+        setRichText(newRt)
 
-          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)) {
-                  set.add(feature.uri)
-                }
+        if (newRt.facets) {
+          for (const facet of newRt.facets) {
+            for (const feature of facet.features) {
+              if (AppBskyRichtextFacet.isLink(feature)) {
+                set.add(feature.uri)
               }
             }
           }
+        }
 
-          if (!isEqual(set, suggestedLinks)) {
-            onSuggestedLinksChanged(set)
-          }
-        },
+        if (!isEqual(set, suggestedLinks)) {
+          onSuggestedLinksChanged(set)
+        }
       },
-      [modeClass],
-    )
+    },
+    [modeClass],
+  )
 
-    const onEmojiInserted = React.useCallback(
-      (emoji: Emoji) => {
-        editor?.chain().focus().insertContent(emoji.native).run()
-      },
-      [editor],
-    )
-    React.useEffect(() => {
-      textInputWebEmitter.addListener('emoji-inserted', onEmojiInserted)
-      return () => {
-        textInputWebEmitter.removeListener('emoji-inserted', onEmojiInserted)
-      }
-    }, [onEmojiInserted])
+  const onEmojiInserted = React.useCallback(
+    (emoji: Emoji) => {
+      editor?.chain().focus().insertContent(emoji.native).run()
+    },
+    [editor],
+  )
+  React.useEffect(() => {
+    textInputWebEmitter.addListener('emoji-inserted', onEmojiInserted)
+    return () => {
+      textInputWebEmitter.removeListener('emoji-inserted', onEmojiInserted)
+    }
+  }, [onEmojiInserted])
 
-    React.useImperativeHandle(ref, () => ({
-      focus: () => {}, // TODO
-      blur: () => {}, // TODO
-    }))
+  React.useImperativeHandle(ref, () => ({
+    focus: () => {}, // TODO
+    blur: () => {}, // TODO
+  }))
 
-    return (
-      <View style={styles.container}>
-        <EditorContent editor={editor} />
-      </View>
-    )
-  },
-)
+  return (
+    <View style={styles.container}>
+      <EditorContent editor={editor} />
+    </View>
+  )
+})
 
 function editorJsonToText(json: JSONContent): string {
   let text = ''