diff --git a/web/chat/chat-input-text-area.react.js b/web/chat/chat-input-text-area.react.js --- a/web/chat/chat-input-text-area.react.js +++ b/web/chat/chat-input-text-area.react.js @@ -11,11 +11,19 @@ +focus: boolean, +currentText: string, +setCurrentText: (text: string) => void, + +onChangePosition: () => void, }; const ChatInputTextArea: React.ComponentType = React.memo( function ChatInputTextArea(props: Props) { - const { currentText, focus, escape, send, setCurrentText } = props; + const { + currentText, + focus, + escape, + send, + setCurrentText, + onChangePosition, + } = props; const textareaRef = React.useRef(null); const focusAndUpdateText = React.useCallback(() => { @@ -48,7 +56,8 @@ const newHeight = Math.min(textarea.scrollHeight, 150); textarea.style.height = `${newHeight}px`; } - }, []); + onChangePosition(); + }, [onChangePosition]); React.useEffect(() => { updateHeight(); diff --git a/web/chat/edit-message-provider.js b/web/chat/edit-message-provider.js --- a/web/chat/edit-message-provider.js +++ b/web/chat/edit-message-provider.js @@ -7,11 +7,19 @@ import type { ChatMessageInfoItem } from 'lib/selectors/chat-selectors.js'; import type { ThreadInfo } from 'lib/types/thread-types'; +export type ModalPosition = { + +left: number, + +top: number, + +width: number, + +height: number, +}; + export type EditState = { +messageInfo: ChatMessageInfoItem, +threadInfo: ThreadInfo, +editedMessageDraft: ?string, +isError: boolean, + +position?: ModalPosition, }; type EditModalContextType = { @@ -20,6 +28,7 @@ +editState: ?EditState, +setDraft: string => void, +setError: boolean => void, + +updatePosition: ModalPosition => void, }; const EditModalContext: React.Context = @@ -29,6 +38,7 @@ editState: null, setDraft: () => {}, setError: () => {}, + updatePosition: () => {}, }); type Props = { @@ -75,6 +85,18 @@ }, [editState, setEditState], ); + + const updatePosition = React.useCallback( + (position: ModalPosition) => { + invariant(editState, 'editState should be set in updatePosition'); + setEditState({ + ...editState, + position, + }); + }, + [editState, setEditState], + ); + const value = React.useMemo( () => ({ renderEditModal, @@ -82,8 +104,16 @@ editState, setDraft, setError, + updatePosition, }), - [renderEditModal, clearEditModal, editState, setDraft, setError], + [ + renderEditModal, + clearEditModal, + editState, + setDraft, + setError, + updatePosition, + ], ); const modalOverlay = React.useMemo(() => { diff --git a/web/chat/edit-text-message.react.js b/web/chat/edit-text-message.react.js --- a/web/chat/edit-text-message.react.js +++ b/web/chat/edit-text-message.react.js @@ -2,6 +2,7 @@ import classNames from 'classnames'; import * as React from 'react'; +import { useCallback } from 'react'; import { XCircle as XCircleIcon } from 'react-feather'; import type { ChatMessageInfoItem } from 'lib/selectors/chat-selectors.js'; @@ -29,10 +30,12 @@ function EditTextMessage(props: Props): React.Node { const { background, threadInfo, item } = props; - const { editState, clearEditModal, setDraft, setError } = + const { editState, clearEditModal, setDraft, setError, updatePosition } = useEditModalContext(); const editMessage = useEditMessage(); + const myRef = React.useRef(null); + const editedMessageDraft = editState?.editedMessageDraft ?? ''; const threadColor = threadInfo.color; const saveButtonColor: ButtonColor = React.useMemo( @@ -71,6 +74,34 @@ } }; + const updateDimensions = useCallback(() => { + if (!myRef.current || !background) { + return; + } + const { left, top, width, height } = myRef.current.getBoundingClientRect(); + updatePosition({ + left, + top, + width, + height, + }); + }, [background, updatePosition]); + + React.useEffect(() => { + if (!background) { + return undefined; + } + window.addEventListener('resize', updateDimensions); + return () => { + window.removeEventListener('resize', updateDimensions); + }; + }, [background, updateDimensions]); + + React.useEffect(() => { + updateDimensions(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + let editFailed; if (editState?.isError) { editFailed = ( @@ -89,12 +120,13 @@ }); return ( -
+