about summary refs log tree commit diff
path: root/src/view
diff options
context:
space:
mode:
Diffstat (limited to 'src/view')
-rw-r--r--src/view/com/composer/Composer.tsx6
-rw-r--r--src/view/com/composer/text-input/TextInput.web.tsx4
-rw-r--r--src/view/com/composer/text-input/textInputWebEmitter.ts3
-rw-r--r--src/view/com/composer/text-input/web/EmojiPicker.web.tsx27
-rw-r--r--src/view/shell/Composer.web.tsx2
5 files changed, 31 insertions, 11 deletions
diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx
index 8ae92b018..3c7868ad2 100644
--- a/src/view/com/composer/Composer.tsx
+++ b/src/view/com/composer/Composer.tsx
@@ -133,7 +133,7 @@ export const ComposePost = observer(function ComposePost({
   quote: initQuote,
   quoteCount,
   mention: initMention,
-  openPicker,
+  openEmojiPicker,
   text: initText,
   imageUris: initImageUris,
   cancelRef,
@@ -520,8 +520,8 @@ export const ComposePost = observer(function ComposePost({
     gallery.size > 0 || Boolean(extLink) || Boolean(videoUploadState.video)
 
   const onEmojiButtonPress = useCallback(() => {
-    openPicker?.(textInput.current?.getCursorPosition())
-  }, [openPicker])
+    openEmojiPicker?.(textInput.current?.getCursorPosition())
+  }, [openEmojiPicker])
 
   const focusTextInput = useCallback(() => {
     textInput.current?.focus()
diff --git a/src/view/com/composer/text-input/TextInput.web.tsx b/src/view/com/composer/text-input/TextInput.web.tsx
index 3c4aaf738..c477ada06 100644
--- a/src/view/com/composer/text-input/TextInput.web.tsx
+++ b/src/view/com/composer/text-input/TextInput.web.tsx
@@ -12,12 +12,12 @@ import {Placeholder} from '@tiptap/extension-placeholder'
 import {Text as TiptapText} from '@tiptap/extension-text'
 import {generateJSON} from '@tiptap/html'
 import {EditorContent, JSONContent, useEditor} from '@tiptap/react'
-import EventEmitter from 'eventemitter3'
 
 import {usePalette} from '#/lib/hooks/usePalette'
 import {useActorAutocompleteFn} from '#/state/queries/actor-autocomplete'
 import {useColorSchemeStyle} from 'lib/hooks/useColorSchemeStyle'
 import {blobToDataUri, isUriImage} from 'lib/media/util'
+import {textInputWebEmitter} from '#/view/com/composer/text-input/textInputWebEmitter'
 import {
   LinkFacetMatch,
   suggestLinkCardUri,
@@ -46,8 +46,6 @@ interface TextInputProps {
   onError: (err: string) => void
 }
 
-export const textInputWebEmitter = new EventEmitter()
-
 export const TextInput = React.forwardRef(function TextInputImpl(
   {
     richtext,
diff --git a/src/view/com/composer/text-input/textInputWebEmitter.ts b/src/view/com/composer/text-input/textInputWebEmitter.ts
new file mode 100644
index 000000000..fb037cac2
--- /dev/null
+++ b/src/view/com/composer/text-input/textInputWebEmitter.ts
@@ -0,0 +1,3 @@
+import EventEmitter from 'eventemitter3'
+
+export const textInputWebEmitter = new EventEmitter()
diff --git a/src/view/com/composer/text-input/web/EmojiPicker.web.tsx b/src/view/com/composer/text-input/web/EmojiPicker.web.tsx
index 1f4178f7f..ad3bb30ec 100644
--- a/src/view/com/composer/text-input/web/EmojiPicker.web.tsx
+++ b/src/view/com/composer/text-input/web/EmojiPicker.web.tsx
@@ -7,8 +7,8 @@ import {
 } from 'react-native'
 import Picker from '@emoji-mart/react'
 
+import {textInputWebEmitter} from '#/view/com/composer/text-input/textInputWebEmitter'
 import {atoms as a} from '#/alf'
-import {textInputWebEmitter} from '../TextInput.web'
 
 const HEIGHT_OFFSET = 40
 const WIDTH_OFFSET = 100
@@ -26,22 +26,41 @@ export type Emoji = {
   unified: string
 }
 
+export interface EmojiPickerPosition {
+  top: number
+  left: number
+  right: number
+  bottom: number
+}
+
 export interface EmojiPickerState {
   isOpen: boolean
-  pos: {top: number; left: number; right: number; bottom: number}
+  pos: EmojiPickerPosition
 }
 
 interface IProps {
   state: EmojiPickerState
   close: () => void
+  /**
+   * If `true`, overrides position and ensures picker is pinned to the top of
+   * the target element.
+   */
+  pinToTop?: boolean
 }
 
-export function EmojiPicker({state, close}: IProps) {
+export function EmojiPicker({state, close, pinToTop}: IProps) {
   const {height, width} = useWindowDimensions()
 
   const isShiftDown = React.useRef(false)
 
   const position = React.useMemo(() => {
+    if (pinToTop) {
+      return {
+        top: state.pos.top - PICKER_HEIGHT + HEIGHT_OFFSET - 10,
+        left: state.pos.left,
+      }
+    }
+
     const fitsBelow = state.pos.top + PICKER_HEIGHT < height
     const fitsAbove = PICKER_HEIGHT < state.pos.top
     const placeOnLeft = PICKER_WIDTH < state.pos.left
@@ -64,7 +83,7 @@ export function EmojiPicker({state, close}: IProps) {
           : undefined,
       }
     }
-  }, [state.pos, height, width])
+  }, [state.pos, height, width, pinToTop])
 
   React.useEffect(() => {
     if (!state.isOpen) return
diff --git a/src/view/shell/Composer.web.tsx b/src/view/shell/Composer.web.tsx
index 5d80dc422..42696139e 100644
--- a/src/view/shell/Composer.web.tsx
+++ b/src/view/shell/Composer.web.tsx
@@ -61,7 +61,7 @@ export function Composer({}: {winHeight: number}) {
           quoteCount={state?.quoteCount}
           onPost={state.onPost}
           mention={state.mention}
-          openPicker={onOpenPicker}
+          openEmojiPicker={onOpenPicker}
           text={state.text}
         />
       </View>