diff --git a/web/src/ui/composer/MessageComposer.css b/web/src/ui/composer/MessageComposer.css index 32c2d31..46e320a 100644 --- a/web/src/ui/composer/MessageComposer.css +++ b/web/src/ui/composer/MessageComposer.css @@ -39,6 +39,14 @@ div.message-composer { > input[type="file"] { display: none; } + + @media screen and (max-width: 45rem) { + margin-right: 0; + + > textarea:not(:empty) { + padding: .5rem 0; + } + } } > div.composer-media, > div.composer-location { diff --git a/web/src/ui/composer/MessageComposer.tsx b/web/src/ui/composer/MessageComposer.tsx index 1177616..5dc5a43 100644 --- a/web/src/ui/composer/MessageComposer.tsx +++ b/web/src/ui/composer/MessageComposer.tsx @@ -13,7 +13,7 @@ // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -import React, { use, useCallback, useEffect, useLayoutEffect, useReducer, useRef, useState } from "react" +import React, { CSSProperties, use, useCallback, useEffect, useLayoutEffect, useReducer, useRef, useState } from "react" import { ScaleLoader } from "react-spinners" import Client from "@/api/client.ts" import { RoomStateStore, usePreference, useRoomEvent } from "@/api/statestore" @@ -46,6 +46,7 @@ import CloseIcon from "@/icons/close.svg?react" import EmojiIcon from "@/icons/emoji-categories/smileys-emotion.svg?react" import GIFIcon from "@/icons/gif.svg?react" import LocationIcon from "@/icons/location.svg?react" +import MoreIcon from "@/icons/more.svg?react" import SendIcon from "@/icons/send.svg?react" import "./MessageComposer.css" @@ -164,9 +165,10 @@ const MessageComposer = () => { }) textInput.current?.focus() }, [room.roomID]) + const canSend = Boolean(state.text || state.media || state.location) const sendMessage = useEvent((evt: React.FormEvent) => { evt.preventDefault() - if (state.text === "" && !state.media && !state.location) { + if (!canSend) { return } if (editing) { @@ -460,7 +462,7 @@ const MessageComposer = () => { + state.text.slice(textInput.current?.selectionEnd ?? 0), })} />, - onClose: () => textInput.current?.focus(), + onClose: () => !isMobileDevice && textInput.current?.focus(), }) }) const openGIFPicker = useEvent(() => { @@ -470,7 +472,7 @@ const MessageComposer = () => { room={roomCtx.store} onSelect={media => setState({ media })} />, - onClose: () => textInput.current?.focus(), + onClose: () => !isMobileDevice && textInput.current?.focus(), }) }) const openLocationPicker = useEvent(() => { @@ -489,6 +491,34 @@ const MessageComposer = () => { mediaDisabledTitle = "Uploading file..." locationDisabledTitle = "You can't attach a location to a message with a file" } + const makeAttachmentButtons = (includeText = false) => { + return <> + + + + + + } + const openButtonsModal = useEvent(() => { + const style: CSSProperties = getEmojiPickerStyle() + style.left = style.right + delete style.right + openModal({ + content:
+ {makeAttachmentButtons(true)} +
, + }) + }) + const inlineButtons = state.text === "" || window.innerWidth > 720 + const showSendButton = canSend || window.innerWidth > 720 return <> {Autocompleter && autocomplete &&
{ location={state.location} onChange={onChangeLocation} clearLocation={clearMedia} />}
+ {!inlineButtons && }