Skip to content

Commit

Permalink
Merge branch 'develop' into newB
Browse files Browse the repository at this point in the history
  • Loading branch information
Yashraj7890 authored Mar 5, 2024
2 parents 88ea004 + da8b930 commit 5e98b25
Show file tree
Hide file tree
Showing 19 changed files with 630 additions and 119 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ _EmbeddedChat is a full-stack React component node module of the RocketChat appl
</div>

## Installation and Usage
Installtion and usage documentation could be found here [EmbeddedChat installation and usage](packages/react/README.md)
Installation and usage documentation could be found here [EmbeddedChat installation and usage](packages/react/README.md)

## Development

Expand Down
20 changes: 20 additions & 0 deletions packages/api/src/EmbeddedChatApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,26 @@ export default class EmbeddedChatApi {
}
}

async getMentionedMessages() {
try {
const { userId, authToken } = (await this.auth.getCurrentUser()) || {};
const response = await fetch(
`${this.host}/api/v1/chat.getMentionedMessages?roomId=${this.rid}`,
{
headers: {
"Content-Type": "application/json",
"X-Auth-Token": authToken,
"X-User-Id": userId,
},
method: "GET",
}
);
return await response.json();
} catch (err) {
console.error(err);
}
}

async pinMessage(mid: string) {
try {
const { userId, authToken } = (await this.auth.getCurrentUser()) || {};
Expand Down
52 changes: 40 additions & 12 deletions packages/react/src/components/Attachments/PinnedAttachment.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,46 @@
import React from 'react';
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import { Box } from '../Box';
import { Avatar } from '../Avatar';
import RCContext from '../../context/RCInstance';

const PinnedAttachment = ({ attachment }) => (
<Box
style={{
borderInlineStart: '1px solid currentColor',
paddingLeft: '0.8rem',
}}
>
<Box>{attachment?.author_name}</Box>
<Box>{attachment?.text}</Box>
</Box>
);
const PinnedAttachment = ({ attachment }) => {
const { RCInstance } = useContext(RCContext);
const getUserAvatarUrl = (authorIcon) => {
const host = RCInstance.getHost();
const URL = `${host}${authorIcon}`;
return URL;
};
return (
<Box
style={{
borderInlineStart: '1px solid currentColor',
paddingLeft: '0.8rem',
}}
>
<Box
style={{
display: 'flex',
gap: '0.3rem',
}}
>
<Avatar
url={getUserAvatarUrl(attachment?.author_icon)}
alt="avatar"
size="1.2em"
/>
<Box>{attachment?.author_name}</Box>
</Box>
<Box
style={{
marginTop: '0.7rem',
}}
>
{attachment?.text}
</Box>
</Box>
);
};

export default PinnedAttachment;

Expand Down
16 changes: 15 additions & 1 deletion packages/react/src/components/ChatHeader/ChatHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
useSearchMessageStore,
useChannelStore,
useToastStore,
useThreadsMessageStore,
useMentionsStore,
} from '../../store';
import { DynamicHeader } from '../DynamicHeader';
import { Tooltip } from '../Tooltip';
Expand All @@ -18,7 +20,6 @@ import useComponentOverrides from '../../theme/useComponentOverrides';
import { Icon } from '../Icon';
import { ActionButton } from '../ActionButton';
import { Menu } from '../Menu';
import useThreadsMessageStore from '../../store/threadsMessageStore';
import { useToastBarDispatch } from '../../hooks/useToastBarDispatch';
import useFetchChatData from '../../hooks/useFetchChatData';

Expand Down Expand Up @@ -73,6 +74,7 @@ const ChatHeader = ({
const setShowAllThreads = useThreadsMessageStore(
(state) => state.setShowAllThreads
);
const setShowMentions = useMentionsStore((state) => state.setShowMentions);
const toastPosition = useToastStore((state) => state.position);

const handleGoBack = async () => {
Expand Down Expand Up @@ -141,6 +143,11 @@ const ChatHeader = ({
setShowSearch(false);
}, [setShowAllThreads, setShowSearch]);

const showMentions = useCallback(async () => {
setShowMentions(true);
setShowSearch(false);
}, [setShowMentions, setShowSearch]);

useEffect(() => {
const setMessageAllowed = async () => {
const permissionRes = await RCInstance.permissionInfo();
Expand Down Expand Up @@ -223,6 +230,12 @@ const ChatHeader = ({
label: 'Threads',
icon: 'thread',
},
{
id: 'mentions',
action: showMentions,
label: 'Mentions',
icon: 'at',
},
{
id: 'members',
action: showChannelMembers,
Expand Down Expand Up @@ -273,6 +286,7 @@ const ChatHeader = ({
moreOpts,
setFullScreen,
showAllThreads,
showMentions,
showChannelMembers,
showChannelinformation,
showPinnedMessage,
Expand Down
129 changes: 79 additions & 50 deletions packages/react/src/components/ChatInput/ChatInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import {
useMessageStore,
loginModalStore,
useChannelStore,
useMemberStore,
} from '../../store';
import ChatInputFormattingToolbar from './ChatInputFormattingToolbar';
import useAttachmentWindowStore from '../../store/attachmentwindow';
import MembersList from '../Mentions/MembersList';
import mentionmemberStore from '../../store/mentionmemberStore';
import { searchToMentionUser } from '../../lib/searchToMentionUser';
import TypingUsers from '../TypingUsers';
import createPendingMessage from '../../lib/createPendingMessage';
Expand All @@ -22,6 +22,7 @@ import { Box } from '../Box';
import { Icon } from '../Icon';
import { CommandsList } from '../CommandList';
import { ActionButton } from '../ActionButton';
import { Divider } from '../Divider';
import useComponentOverrides from '../../theme/useComponentOverrides';
import { useToastBarDispatch } from '../../hooks/useToastBarDispatch';

Expand All @@ -45,12 +46,23 @@ const ChatInput = ({ scrollToBottom }) => {
(state) => state.setIsUserAuthenticated
);

const isChannelPrivate = useChannelStore((state) => state.isChannelPrivate);

const members = useMemberStore((state) => state.members);
const setMembersHandler = useMemberStore((state) => state.setMembersHandler);

useEffect(() => {
RCInstance.auth.onAuthChange((user) => {
if (user) {
RCInstance.getCommandsList()
.then((data) => setCommands(data.commands || []))
.catch(console.error);

RCInstance.getChannelMembers(isChannelPrivate)
.then((channelMembers) =>
setMembersHandler(channelMembers.members || [])
)
.catch(console.error);
}
});
}, [RCInstance]);
Expand All @@ -68,28 +80,19 @@ const ChatInput = ({ scrollToBottom }) => {

const inputRef = useRef(null);
const typingRef = useRef();
const messageRef = useRef();
const messageRef = useRef(null);

const [disableButton, setDisableButton] = useState(true);

const roomMembers = mentionmemberStore((state) => state.roomMembers);
const setRoomMembers = mentionmemberStore((state) => state.setRoomMembers);

const [filteredMembers, setFilteredMembers] = useState([]);

const [mentionIndex, setmentionIndex] = useState(-1);
const [startReading, setStartReading] = useState(false);
const showMembersList = mentionmemberStore((state) => state.showMembersList);
const setshowMembersList = mentionmemberStore(
(state) => state.toggleShowMembers
);
const [showMembersList, setshowMembersList] = useState(false);

const setIsLoginModalOpen = loginModalStore(
(state) => state.setIsLoginModalOpen
);
const isChannelPrivate = useChannelStore((state) => state.isChannelPrivate);
const setIsChannelPrivate = useChannelStore(
(state) => state.setIsChannelPrivate
);

const {
editMessage,
Expand Down Expand Up @@ -143,7 +146,7 @@ const ChatInput = ({ scrollToBottom }) => {
};

const sendMessage = async () => {
scrollToBottom();
messageRef.current.focus();
messageRef.current.style.height = '44px';
const message = messageRef.current.value.trim();
if (!message.length || !isUserAuthenticated) {
Expand Down Expand Up @@ -207,6 +210,8 @@ const ChatInput = ({ scrollToBottom }) => {
setDisableButton(true);
setEditMessage({});
}

scrollToBottom();
};

const sendAttachment = (event) => {
Expand All @@ -217,16 +222,6 @@ const ChatInput = ({ scrollToBottom }) => {
toggle();
setData(event.target.files[0]);
};
const getAllChannelMembers = useCallback(async () => {
try {
const channelMembers = await RCInstance.getChannelMembers(
isChannelPrivate
);
setRoomMembers(channelMembers.members);
} catch (e) {
console.error(e);
}
}, [RCInstance, setRoomMembers, isChannelPrivate]);

useEffect(() => {
if (editMessage.msg) {
Expand All @@ -235,9 +230,6 @@ const ChatInput = ({ scrollToBottom }) => {
messageRef.current.value = '';
}
}, [editMessage]);
useEffect(() => {
getAllChannelMembers();
}, [getAllChannelMembers]);

const username = useUserStore((state) => state.username);
const timerRef = useRef();
Expand Down Expand Up @@ -285,6 +277,34 @@ const ChatInput = ({ scrollToBottom }) => {
}
}, []);

const handleMemberClick = (selectedItem) => {
setshowMembersList(false);

let insertionText;
if (selectedItem === 'all') {
insertionText = `${messageRef.current.value.substring(
0,
messageRef.current.value.lastIndexOf('@')
)}@all `;
} else if (selectedItem === 'here') {
insertionText = `${messageRef.current.value.substring(
0,
messageRef.current.value.lastIndexOf('@')
)}@here `;
} else {
insertionText = `${messageRef.current.value.substring(
0,
messageRef.current.value.lastIndexOf('@')
)}@${selectedItem.username} `;
}

messageRef.current.value = insertionText;

const cursorPosition = insertionText.length;
messageRef.current.setSelectionRange(cursorPosition, cursorPosition);
messageRef.current.focus();
};

const showCommands = useCallback(
async (e) => {
const cursor = e.target.selectionStart;
Expand Down Expand Up @@ -320,7 +340,7 @@ const ChatInput = ({ scrollToBottom }) => {
}
searchToMentionUser(
messageRef.current.value,
roomMembers,
members,
startReading,
setStartReading,
setFilteredMembers,
Expand Down Expand Up @@ -386,36 +406,41 @@ const ChatInput = ({ scrollToBottom }) => {
}

if (e.key === 'ArrowDown') {
e.preventDefault();
setmentionIndex(
mentionIndex + 1 >= filteredMembers.length + 2 ? 0 : mentionIndex + 1
);
}
if (e.key === 'ArrowUp') {
e.preventDefault();
setmentionIndex(
mentionIndex - 1 < 0 ? filteredMembers.length + 1 : mentionIndex - 1
);
}
if (showMembersList && e.key === 'Enter') {
e.preventDefault();
let selectedMember = null;
if (mentionIndex === filteredMembers.length) selectedMember = 'all';
else if (mentionIndex === filteredMembers.length + 1)
selectedMember = 'everyone';
else selectedMember = filteredMembers[mentionIndex].username;
messageRef.current.value = `${messageRef.current.value.substring(
0,
messageRef.current.value.lastIndexOf('@')
)}@${selectedMember}`;

setshowMembersList(false);

setStartReading(false);
setFilteredMembers([]);
setmentionIndex(-1);
const lastIndexOfAt = messageRef.current.value.lastIndexOf('@');
const cursorPosition = lastIndexOfAt === -1 ? 0 : lastIndexOfAt + 1;
messageRef.current.setSelectionRange(cursorPosition, cursorPosition);
}

if (e.key === 'Enter') {
sendTypingStop();
e.preventDefault();
if (showMembersList) {
let selectedMember = null;
if (mentionIndex === filteredMembers.length) selectedMember = 'all';
else if (mentionIndex === filteredMembers.length + 1)
selectedMember = 'here';
else selectedMember = filteredMembers[mentionIndex].username;

handleMemberClick(selectedMember);

setshowMembersList(false);
setStartReading(false);
setFilteredMembers([]);
setmentionIndex(-1);
} else {
sendTypingStop();
sendMessage();
}
}
};
return (
Expand All @@ -434,10 +459,14 @@ const ChatInput = ({ scrollToBottom }) => {
`}
>
{showMembersList ? (
<MembersList
mentionIndex={mentionIndex}
filteredMembers={filteredMembers}
/>
<>
<MembersList
mentionIndex={mentionIndex}
filteredMembers={filteredMembers}
onMemberClick={handleMemberClick}
/>
<Divider />
</>
) : (
<></>
)}
Expand Down
Loading

0 comments on commit 5e98b25

Please sign in to comment.