about summary refs log tree commit diff
path: root/src/screens/Messages/Conversation/MessageInput.web.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/screens/Messages/Conversation/MessageInput.web.tsx')
-rw-r--r--src/screens/Messages/Conversation/MessageInput.web.tsx66
1 files changed, 65 insertions, 1 deletions
diff --git a/src/screens/Messages/Conversation/MessageInput.web.tsx b/src/screens/Messages/Conversation/MessageInput.web.tsx
index a4a8a7852..0b7e47920 100644
--- a/src/screens/Messages/Conversation/MessageInput.web.tsx
+++ b/src/screens/Messages/Conversation/MessageInput.web.tsx
@@ -12,9 +12,16 @@ import {
 } from '#/state/messages/message-drafts'
 import {isSafari, isTouchDevice} from 'lib/browser'
 import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
+import {textInputWebEmitter} from '#/view/com/composer/text-input/textInputWebEmitter'
+import {
+  Emoji,
+  EmojiPickerPosition,
+} from '#/view/com/composer/text-input/web/EmojiPicker.web'
 import * as Toast from '#/view/com/util/Toast'
 import {atoms as a, useTheme} from '#/alf'
+import {Button} from '#/components/Button'
 import {useSharedInputStyles} from '#/components/forms/TextField'
+import {EmojiArc_Stroke2_Corner0_Rounded as EmojiSmile} from '#/components/icons/Emoji'
 import {PaperPlane_Stroke2_Corner0_Rounded as PaperPlane} from '#/components/icons/PaperPlane'
 import {useExtractEmbedFromFacets} from './MessageInputEmbed'
 
@@ -23,11 +30,13 @@ export function MessageInput({
   hasEmbed,
   setEmbed,
   children,
+  openEmojiPicker,
 }: {
   onSendMessage: (message: string) => void
   hasEmbed: boolean
   setEmbed: (embedUrl: string | undefined) => void
   children?: React.ReactNode
+  openEmojiPicker?: (pos: EmojiPickerPosition) => void
 }) {
   const {isTabletOrDesktop} = useWebMediaQueries()
   const {_} = useLingui()
@@ -40,6 +49,7 @@ export function MessageInput({
   const [isFocused, setIsFocused] = React.useState(false)
   const [isHovered, setIsHovered] = React.useState(false)
   const [textAreaHeight, setTextAreaHeight] = React.useState(38)
+  const textAreaRef = React.useRef<HTMLTextAreaElement>(null)
 
   const onSubmit = React.useCallback(() => {
     if (!hasEmbed && message.trim() === '') {
@@ -94,6 +104,23 @@ export function MessageInput({
     [],
   )
 
+  const onEmojiInserted = React.useCallback(
+    (emoji: Emoji) => {
+      const position = textAreaRef.current?.selectionStart ?? 0
+      setMessage(
+        message =>
+          message.slice(0, position) + emoji.native + message.slice(position),
+      )
+    },
+    [setMessage],
+  )
+  React.useEffect(() => {
+    textInputWebEmitter.addListener('emoji-inserted', onEmojiInserted)
+    return () => {
+      textInputWebEmitter.removeListener('emoji-inserted', onEmojiInserted)
+    }
+  }, [onEmojiInserted])
+
   useSaveMessageDraft(message)
   useExtractEmbedFromFacets(message, setEmbed)
 
@@ -106,7 +133,7 @@ export function MessageInput({
           t.atoms.bg_contrast_25,
           {
             paddingRight: a.p_sm.padding - 2,
-            paddingLeft: a.p_md.padding - 2,
+            paddingLeft: a.p_sm.padding - 2,
             borderWidth: 1,
             borderRadius: 23,
             borderColor: 'transparent',
@@ -118,7 +145,44 @@ export function MessageInput({
         // @ts-expect-error web only
         onMouseEnter={() => setIsHovered(true)}
         onMouseLeave={() => setIsHovered(false)}>
+        <Button
+          onPress={e => {
+            e.currentTarget.measure((_fx, _fy, _width, _height, px, py) => {
+              openEmojiPicker?.({top: py, left: px, right: px, bottom: py})
+            })
+          }}
+          style={[
+            a.rounded_full,
+            a.overflow_hidden,
+            a.align_center,
+            a.justify_center,
+            {
+              marginTop: 5,
+              height: 30,
+              width: 30,
+            },
+          ]}
+          label={_(msg`Open emoji picker`)}>
+          {state => (
+            <View
+              style={[
+                a.absolute,
+                a.inset_0,
+                a.align_center,
+                a.justify_center,
+                {
+                  backgroundColor:
+                    state.hovered || state.focused || state.pressed
+                      ? t.atoms.bg.backgroundColor
+                      : undefined,
+                },
+              ]}>
+              <EmojiSmile size="lg" />
+            </View>
+          )}
+        </Button>
         <TextareaAutosize
+          ref={textAreaRef}
           style={StyleSheet.flatten([
             a.flex_1,
             a.px_sm,