diff --git a/src/index.d.ts b/src/index.d.ts index 43c2027c8..4ecdca0dd 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -377,8 +377,8 @@ interface ChannelProps { onSearchClick?(): void; highlightedMessage?: string | number; startingPoint?: number; - onBeforeSendUserMessage?(text: string, quoteMessage?: Sendbird.UserMessage | Sendbird.FileMessage): Sendbird.UserMessageParams; - onBeforeSendFileMessage?(file: File, quoteMessage?: Sendbird.UserMessage | Sendbird.FileMessage): Sendbird.FileMessageParams; + onBeforeSendUserMessage?(text: string, quotedMessage?: Sendbird.UserMessage | Sendbird.FileMessage): Sendbird.UserMessageParams; + onBeforeSendFileMessage?(file: File, quotedMessage?: Sendbird.UserMessage | Sendbird.FileMessage): Sendbird.FileMessageParams; onBeforeUpdateUserMessage?(text: string): Sendbird.UserMessageParams; onChatHeaderActionClick?(event: React.MouseEvent): void; renderCustomMessage?: RenderCustomMessage; diff --git a/src/smart-components/App/stories/index.stories.js b/src/smart-components/App/stories/index.stories.js index 0af0e787a..642912e78 100644 --- a/src/smart-components/App/stories/index.stories.js +++ b/src/smart-components/App/stories/index.stories.js @@ -278,6 +278,32 @@ const UseSendbirdChannelList = (props) => { ); }; const SBChannelList = withSendBird(UseSendbirdChannelList); +const SBChannel = withSendBird((props) => { + const { + channelUrl, + onSearchClick, + onChatHeaderActionClick, + showSearchIcon, + } = props; + + return ( + { + // if (message.messageType === 'user') { + // return () => ( + // + // ) + // } + // }} + /> + ); +}); const CustomApp = () => { const [channelUrl, setChannelUrl] = useState(''); const [channelSettings, setChannelSettings] = useState(false); @@ -297,7 +323,7 @@ const CustomApp = () => {
- { setChannelSearch(false); diff --git a/src/smart-components/Conversation/components/ConversationScroll.jsx b/src/smart-components/Conversation/components/ConversationScroll.jsx index 6fdeadc4f..d7c2c2d40 100644 --- a/src/smart-components/Conversation/components/ConversationScroll.jsx +++ b/src/smart-components/Conversation/components/ConversationScroll.jsx @@ -10,7 +10,26 @@ import { compareMessagesForGrouping } from '../utils'; import PlaceHolder, { PlaceHolderTypes } from '../../../ui/PlaceHolder'; import Icon, { IconTypes, IconColors } from '../../../ui/Icon'; +const SCROLL_REF_CLASS_NAME = '.sendbird-msg--scroll-ref'; + export default class ConversationScroll extends Component { + constructor(props) { + super(props); + this.state = {}; + } + + handleScroll = () => { + const { scrollRef } = this?.props; + const current = scrollRef?.current; + if (current) { + const bottom = current.scrollHeight - current.scrollTop - current.offsetHeight; + const { scrollBottom = 0 } = this.state; + if (scrollBottom < bottom) { + current.scrollTop += bottom - scrollBottom; + } + } + } + onScroll = (e) => { const { scrollRef, @@ -31,7 +50,7 @@ export default class ConversationScroll extends Component { if (!hasMore) { return; } - const nodes = scrollRef.current.querySelectorAll('.sendbird-msg--scroll-ref'); + const nodes = scrollRef.current.querySelectorAll(SCROLL_REF_CLASS_NAME); const first = nodes && nodes[0]; onScroll(([messages]) => { if (messages) { @@ -46,7 +65,7 @@ export default class ConversationScroll extends Component { } if (clientHeight + scrollTop === scrollHeight) { - const nodes = scrollRef.current.querySelectorAll('.sendbird-msg--scroll-ref'); + const nodes = scrollRef.current.querySelectorAll(SCROLL_REF_CLASS_NAME); const last = nodes && nodes[nodes.length - 1]; onScrollDown(([messages]) => { if (messages) { @@ -69,6 +88,15 @@ export default class ConversationScroll extends Component { }); currentGroupChannel.markAsRead(); } + + // save the lastest scroll bottom value + if (scrollRef?.current) { + const current = scrollRef?.current; + this.setState((state) => ({ + ...state, + scrollBottom: current.scrollHeight - current.scrollTop - current.offsetHeight, + }), () => { }); + } }, 500); } @@ -113,11 +141,7 @@ export default class ConversationScroll extends Component { return (
-
+
{/* To do: Implement windowing @@ -126,7 +150,11 @@ export default class ConversationScroll extends Component { We hesitate to bring one more dependency to our library, we are planning to implement it inside the library */} -
+
{ allMessages.map( (m, idx) => { @@ -176,7 +204,7 @@ export default class ConversationScroll extends Component { renderCustomMessage={renderCustomMessage} key={m.messageId || m.reqId} userId={userId} - // show status for pending/failed messages + handleScroll={this.handleScroll} message={m} quoteMessage={quoteMessage} scrollToMessage={scrollToMessage} @@ -292,8 +320,8 @@ ConversationScroll.defaultProps = { replyType: 'NONE', emojiContainer: {}, showScrollBot: false, - onClickScrollBot: () => {}, - scrollToMessage: () => {}, + onClickScrollBot: () => { }, + scrollToMessage: () => { }, emojiAllMap: new Map(), membersMap: new Map(), useMessageGrouping: true, diff --git a/src/smart-components/Conversation/components/MessageHOC.jsx b/src/smart-components/Conversation/components/MessageHOC.jsx index ff6c7172b..04500b3bc 100644 --- a/src/smart-components/Conversation/components/MessageHOC.jsx +++ b/src/smart-components/Conversation/components/MessageHOC.jsx @@ -38,6 +38,7 @@ export default function MessageHoc({ setQuoteMessage, renderCustomMessage, currentGroupChannel, + handleScroll, }) { const { sender = {} } = message; const [showEdit, setShowEdit] = useState(false); @@ -48,6 +49,10 @@ export default function MessageHoc({ const editMessageInputRef = useRef(null); const useMessageScrollRef = useRef(null); + useLayoutEffect(() => { + handleScroll(); + }, [showEdit, message?.reactions?.length]); + useLayoutEffect(() => { if (highLightedMessageId === message.messageId) { if (useMessageScrollRef && useMessageScrollRef.current) { @@ -166,7 +171,9 @@ export default function MessageHoc({ replyType={replyType} nicknamesMap={membersMap} emojiContainer={emojiContainer} - showEdit={setShowEdit} + showEdit={() => { + setShowEdit(true); + }} showRemove={setShowRemove} showFileViewer={setShowFileViewer} resendMessage={resendMessage} @@ -224,6 +231,7 @@ MessageHoc.propTypes = { sender: PropTypes.shape({ userId: PropTypes.string }), ogMetaData: PropTypes.shape({}), parentMessageId: PropTypes.number, + reactions: PropTypes.arrayOf(PropTypes.number), }), animatedMessageId: PropTypes.oneOfType([ PropTypes.string, @@ -260,6 +268,7 @@ MessageHoc.propTypes = { messageId: PropTypes.string, }), setQuoteMessage: PropTypes.func.isRequired, + handleScroll: PropTypes.func.isRequired, }; MessageHoc.defaultProps = { diff --git a/src/smart-components/Conversation/components/conversation-scroll.scss b/src/smart-components/Conversation/components/conversation-scroll.scss index a5403fcf4..1697276e9 100644 --- a/src/smart-components/Conversation/components/conversation-scroll.scss +++ b/src/smart-components/Conversation/components/conversation-scroll.scss @@ -4,6 +4,8 @@ .sendbird-conversation__messages-padding { padding-left: 24px; padding-right: 24px; + height: 100%; + overflow: scroll; } .sendbird-separator, .sendbird-admin-message { diff --git a/src/smart-components/Conversation/utils.js b/src/smart-components/Conversation/utils.js index 07c7f08ce..f0a3aae65 100644 --- a/src/smart-components/Conversation/utils.js +++ b/src/smart-components/Conversation/utils.js @@ -18,7 +18,7 @@ export const scrollIntoLast = (intialTry = 0) => { return; } try { - const scrollDOM = document.querySelector('.sendbird-conversation__scroll-container'); + const scrollDOM = document.querySelector('.sendbird-conversation__messages-padding'); // eslint-disable-next-line no-multi-assign scrollDOM.scrollTop = scrollDOM.scrollHeight; } catch (error) { diff --git a/src/ui/MessageItemMenu/index.tsx b/src/ui/MessageItemMenu/index.tsx index 20ac7fd83..b41f2a15f 100644 --- a/src/ui/MessageItemMenu/index.tsx +++ b/src/ui/MessageItemMenu/index.tsx @@ -23,7 +23,7 @@ interface Props { isByMe?: boolean; disabled?: boolean; replyType?: ReplyType; - showEdit?: (bool: boolean) => void; + showEdit?: () => void; showRemove?: (bool: boolean) => void; resendMessage?: (message: UserMessage | FileMessage) => void; setQuoteMessage?: (message: UserMessage | FileMessage) => void; @@ -126,7 +126,8 @@ export default function MessageItemMenu({ className="sendbird-message-item-menu__list__menu-item menu-item-edit" onClick={() => { if (!disabled) { - showEdit(true); + // showEdit(true); + showEdit(); closeDropdown(); } }}