diff --git a/packages/react/src/views/ChatInput/AudioMessageRecorder.js b/packages/react/src/views/ChatInput/AudioMessageRecorder.js
index 9ff497a30f..53dbddf4bd 100644
--- a/packages/react/src/views/ChatInput/AudioMessageRecorder.js
+++ b/packages/react/src/views/ChatInput/AudioMessageRecorder.js
@@ -11,7 +11,8 @@ import useMessageStore from '../../store/messageStore';
import { getCommonRecorderStyles } from './ChatInput.styles';
import useAttachmentWindowStore from '../../store/attachmentwindow';
-const AudioMessageRecorder = ({ disabled }) => {
+const AudioMessageRecorder = (props) => {
+ const { disabled, displayName, popOverItemStyles } = props;
const videoRef = useRef(null);
const { theme } = useTheme();
const styles = getCommonRecorderStyles(theme);
@@ -136,7 +137,17 @@ const AudioMessageRecorder = ({ disabled }) => {
}, [isRecorded, file]);
if (state === 'idle') {
- return (
+ return displayName ? (
+
+
+ {displayName}
+
+ ) : (
{
disabled={!isUserAuthenticated || !canSendMsg || isRecordingMessage}
placeholder={
isUserAuthenticated && canSendMsg
- ? `Message #${channelInfo.name}`
+ ? `Message ${channelInfo.name ? `#${channelInfo.name}` : ''}`
: isUserAuthenticated
? 'This room is read only'
: 'Sign in to chat'
diff --git a/packages/react/src/views/ChatInput/ChatInput.styles.js b/packages/react/src/views/ChatInput/ChatInput.styles.js
index 21e7a24736..b193d06922 100644
--- a/packages/react/src/views/ChatInput/ChatInput.styles.js
+++ b/packages/react/src/views/ChatInput/ChatInput.styles.js
@@ -10,6 +10,10 @@ export const getChatInputStyles = (theme) => {
&.focused {
border: ${`1.5px solid ${theme.colors.ring}`};
}
+ @media (max-width: 500px) {
+ margin: 0;
+ width: 100%;
+ }
`,
editMessage: css`
@@ -80,10 +84,27 @@ export const getChatInputFormattingToolbarStyles = ({ theme, mode }) => {
position: relative;
gap: 0.1rem;
border-radius: 0 0 ${theme.radius} ${theme.radius};
- @media (max-width: 383px) {
- display: grid;
- grid-template-columns: repeat(5, 0.2fr);
- }
+ `,
+ popOverStyles: css`
+ position: absolute;
+ bottom: 3rem;
+ left: 0;
+ width: 100%;
+ background: ${theme.colors.background};
+ box-shadow: 0 -8px 10px ${mode === 'light' ? darken(theme.colors.background, 0.1) : lighten(theme.colors.background, 1)};
+ border-radius: 8px;
+ padding: 1rem;
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ z-index: 1300;
+ `,
+ popOverItemStyles: css`
+ display: flex;
+ gap: 0.5rem;
+ align-items: center;
+ cursor: pointer;
+ padding: 0.5rem;
`,
};
return styles;
@@ -101,8 +122,8 @@ export const getCommonRecorderStyles = (theme) => {
`,
controller: css`
- display: flex;
gap: 0.15rem;
+ display: inline-flex;
`,
timer: css`
diff --git a/packages/react/src/views/ChatInput/ChatInputFormattingToolbar.js b/packages/react/src/views/ChatInput/ChatInputFormattingToolbar.js
index 523b9ef976..5d8c20a600 100644
--- a/packages/react/src/views/ChatInput/ChatInputFormattingToolbar.js
+++ b/packages/react/src/views/ChatInput/ChatInputFormattingToolbar.js
@@ -1,4 +1,4 @@
-import React, { useState } from 'react';
+import React, { useState, useRef, useEffect } from 'react';
import { css } from '@emotion/react';
import {
Box,
@@ -24,6 +24,8 @@ const ChatInputFormattingToolbar = ({
optionConfig = {
surfaceItems: ['emoji', 'formatter', 'link', 'audio', 'video', 'file'],
formatters: ['bold', 'italic', 'strike', 'code', 'multiline'],
+ smallScreenSurfaceItems: ['emoji', 'video', 'audio', 'file'],
+ popOverItems: ['formatter', 'link'],
},
}) => {
const { classNames, styleOverrides, configOverrides } = useComponentOverrides(
@@ -35,18 +37,27 @@ const ChatInputFormattingToolbar = ({
configOverrides.optionConfig?.surfaceItems || optionConfig.surfaceItems;
const formatters =
configOverrides.optionConfig?.formatters || optionConfig.formatters;
-
+ const smallScreenSurfaceItems =
+ configOverrides.optionConfig?.smallScreenSurfaceItems ||
+ optionConfig.smallScreenSurfaceItems;
+ const popOverItems =
+ configOverrides.optionConfig?.popOverItems || optionConfig.popOverItems;
const isRecordingMessage = useMessageStore(
(state) => state.isRecordingMessage
);
const [isEmojiOpen, setEmojiOpen] = useState(false);
const [isInsertLinkOpen, setInsertLinkOpen] = useState(false);
+ const [isPopoverOpen, setPopoverOpen] = useState(false);
+ const popoverRef = useRef(null);
const handleClickToOpenFiles = () => {
inputRef.current.click();
};
-
+ const handleFormatterClick = (item) => {
+ formatSelection(messageRef, item.pattern);
+ setPopoverOpen(false);
+ };
const handleEmojiClick = (emojiEvent) => {
const [emoji] = emojiEvent.names;
const message = `${messageRef.current.value} :${emoji.replace(
@@ -73,77 +84,158 @@ const ChatInputFormattingToolbar = ({
};
const chatToolMap = {
- emoji: (
-
- {
if (isRecordingMessage) return;
setEmojiOpen(true);
}}
>
-
-
-
+
+ emoji
+
+ ) : (
+
+ {
+ if (isRecordingMessage) return;
+ setEmojiOpen(true);
+ }}
+ >
+
+
+
+ ),
+
+ audio: (
+
),
- audio: ,
- video: ,
- file: (
-
-
+ ),
+ file:
+ isPopoverOpen && popOverItems.includes('file') ? (
+ {
if (isRecordingMessage) return;
handleClickToOpenFiles();
}}
>
-
-
-
- ),
- link: (
-
-
+ file
+
+ ) : (
+
+ {
+ if (isRecordingMessage) return;
+ handleClickToOpenFiles();
+ }}
+ >
+
+
+
+ ),
+ link:
+ isPopoverOpen && popOverItems.includes('link') ? (
+ {
+ if (isRecordingMessage) return;
setInsertLinkOpen(true);
}}
>
-
-
-
- ),
- formatter: formatters
- .map((name) => formatter.find((item) => item.name === name))
- .map((item) => (
-
+
+ link
+
+ ) : (
+
{
if (isRecordingMessage) return;
- formatSelection(messageRef, item.pattern);
+ setInsertLinkOpen(true);
}}
>
-
+
- )),
+ ),
+ formatter: formatters
+ .map((name) => formatter.find((item) => item.name === name))
+ .map((item) =>
+ isPopoverOpen && popOverItems.includes('formatter') ? (
+ <>
+ {
+ if (isRecordingMessage) return;
+ handleFormatterClick(item);
+ }}
+ css={styles.popOverItemStyles}
+ >
+
+ {item.name}
+
+ >
+ ) : (
+
+ {
+ if (isRecordingMessage) return;
+ formatSelection(messageRef, item.pattern);
+ }}
+ >
+
+
+
+ )
+ ),
};
return (
@@ -152,8 +244,95 @@ const ChatInputFormattingToolbar = ({
className={`ec-chat-input-formatting-toolbar ${classNames}`}
style={styleOverrides}
>
- {surfaceItems.map((key) => chatToolMap[key])}
+
+ {surfaceItems.map((key) => chatToolMap[key])}
+
+ {isPopoverOpen && (
+
+ {popOverItems.map((name) => {
+ const itemInFormatter = formatter.find(
+ (item) => item.name === name
+ );
+ if (itemInFormatter) {
+ return (
+ handleFormatterClick(itemInFormatter)}
+ css={styles.popOverItemStyles}
+ >
+
+ {itemInFormatter.name}
+
+ );
+ }
+ return chatToolMap[name];
+ })}
+
+ )}
+
+ {smallScreenSurfaceItems.map((name) => {
+ const itemInFormatter = formatter.find((item) => item.name === name);
+ if (itemInFormatter) {
+ return (
+
+
+ formatSelection(messageRef, itemInFormatter.pattern)
+ }
+ >
+
+
+
+ );
+ }
+ return chatToolMap[name];
+ })}
+ {popOverItems.length > 0 && (
+
+ {
+ if (isRecordingMessage) return;
+ setPopoverOpen(!isPopoverOpen);
+ }}
+ >
+
+
+
+ )}
+
{isEmojiOpen && (
)}
diff --git a/packages/react/src/views/ChatInput/VideoMessageRecoder.js b/packages/react/src/views/ChatInput/VideoMessageRecoder.js
index eeb8c394e0..814c2093aa 100644
--- a/packages/react/src/views/ChatInput/VideoMessageRecoder.js
+++ b/packages/react/src/views/ChatInput/VideoMessageRecoder.js
@@ -13,8 +13,9 @@ import useMessageStore from '../../store/messageStore';
import { getCommonRecorderStyles } from './ChatInput.styles';
import useAttachmentWindowStore from '../../store/attachmentwindow';
-const VideoMessageRecorder = ({ disabled }) => {
+const VideoMessageRecorder = (props) => {
const videoRef = useRef(null);
+ const { disabled, displayName, popOverItemStyles } = props;
const { theme } = useTheme();
const styles = getCommonRecorderStyles(theme);
@@ -146,18 +147,29 @@ const VideoMessageRecorder = ({ disabled }) => {
return (
<>
- {state === 'idle' && (
-
-
-
-
-
- )}
+
+ {displayName}
+
+ ) : (
+
+
+
+
+
+ ))}
{state === 'recording' && (
<>
diff --git a/packages/react/src/views/QuoteMessage/QuoteMessage.styles.js b/packages/react/src/views/QuoteMessage/QuoteMessage.styles.js
index 1b6619ea95..61c5c8d05f 100644
--- a/packages/react/src/views/QuoteMessage/QuoteMessage.styles.js
+++ b/packages/react/src/views/QuoteMessage/QuoteMessage.styles.js
@@ -14,6 +14,11 @@ const getQuoteMessageStyles = (theme) => {
border-radius: ${theme.radius};
max-width: 100%;
box-sizing: border-box;
+
+ @media (max-width: 500px) {
+ margin: 0;
+ width: 100%;
+ }
`,
avatarContainer: css`