From 658c292cbf07c09209e99e244fad8241bfb9f612 Mon Sep 17 00:00:00 2001 From: Anirban Singha Date: Fri, 27 Dec 2024 18:07:30 +0530 Subject: [PATCH] feat: add unstar, unpin, copy link, and navigate options in starred and pinned files list --- .../MessageAggregators/PinnedMessages.js | 28 +++++- .../MessageAggregators/StarredMessages.js | 25 ++++- .../common/MessageAggregator.js | 94 ++++++++++++++++--- .../common/MessageAggregator.styles.js | 2 + 4 files changed, 132 insertions(+), 17 deletions(-) diff --git a/packages/react/src/views/MessageAggregators/PinnedMessages.js b/packages/react/src/views/MessageAggregators/PinnedMessages.js index 884e13529c..77ba07b835 100644 --- a/packages/react/src/views/MessageAggregators/PinnedMessages.js +++ b/packages/react/src/views/MessageAggregators/PinnedMessages.js @@ -1,14 +1,38 @@ -import React from 'react'; -import { useComponentOverrides } from '@embeddedchat/ui-elements'; +import React, { useContext } from 'react'; +import { + useComponentOverrides, + useToastBarDispatch, +} from '@embeddedchat/ui-elements'; import { MessageAggregator } from './common/MessageAggregator'; +import RCContext from '../../context/RCInstance'; const PinnedMessages = () => { const { variantOverrides } = useComponentOverrides('PinnedMessages'); const viewType = variantOverrides.viewType || 'Sidebar'; + const { RCInstance } = useContext(RCContext); + const dispatchToastMessage = useToastBarDispatch(); + + const unpin = async (msg) => { + const isPinned = msg.pinned; + const Unpin = await RCInstance.unpinMessage(msg._id); + if (Unpin.error) { + dispatchToastMessage({ + type: 'error', + message: 'Error pinning message', + }); + } else { + dispatchToastMessage({ + type: 'success', + message: isPinned ? 'Message unpinned' : 'Message pinned', + }); + } + }; return ( msg.pinned} viewType={viewType} diff --git a/packages/react/src/views/MessageAggregators/StarredMessages.js b/packages/react/src/views/MessageAggregators/StarredMessages.js index 5ced944f06..0be1e1b22c 100644 --- a/packages/react/src/views/MessageAggregators/StarredMessages.js +++ b/packages/react/src/views/MessageAggregators/StarredMessages.js @@ -1,7 +1,11 @@ -import React, { useCallback, useEffect } from 'react'; -import { useComponentOverrides } from '@embeddedchat/ui-elements'; +import React, { useCallback, useContext } from 'react'; +import { + useComponentOverrides, + useToastBarDispatch, +} from '@embeddedchat/ui-elements'; import { useStarredMessageStore, useUserStore } from '../../store'; import { MessageAggregator } from './common/MessageAggregator'; +import RCContext from '../../context/RCInstance'; const StarredMessages = () => { const authenticatedUserId = useUserStore((state) => state.userId); @@ -10,16 +14,33 @@ const StarredMessages = () => { const starredMessages = useStarredMessageStore( (state) => state.starredMessages ); + const setStarredMessages = useStarredMessageStore( + (state) => state.setStarredMessages + ); + const dispatchToastMessage = useToastBarDispatch(); + const { RCInstance } = useContext(RCContext); const shouldRender = useCallback( (msg) => msg.starred && msg.starred.some((star) => star._id === authenticatedUserId), [authenticatedUserId] ); + + const unstar = async (msg) => { + await RCInstance.unstarMessage(msg._id); + dispatchToastMessage({ + type: 'success', + message: 'Message unstarred', + }); + setStarredMessages(starredMessages.filter((str) => str._id !== msg._id)); + }; + return ( state.messages); const threadMessages = useMessageStore((state) => state.threadMessages) || []; const allMessages = useMemo( @@ -44,6 +52,7 @@ export const MessageAggregator = ({ fetchedMessageList || searchFiltered || allMessages, shouldRender ); + const dispatchToastMessage = useToastBarDispatch(); const setShowSidebar = useSidebarStore((state) => state.setShowSidebar); const setJumpToMessage = (msgId) => { @@ -56,6 +65,28 @@ export const MessageAggregator = ({ } }; + const getMessageLink = async (id) => { + const host = await RCInstance.getHost(); + const res = await RCInstance.channelInfo(); + return `${host}/channel/${res.room.name}/?msg=${id}`; + }; + + const copyLink = async (id) => { + try { + const messageLink = await getMessageLink(id); + await navigator.clipboard.writeText(messageLink); + dispatchToastMessage({ + type: 'success', + message: 'Message link copied successfully', + }); + } catch (err) { + dispatchToastMessage({ + type: 'error', + message: 'Error in copying message link', + }); + } + }; + const isMessageNewDay = (current, previous) => !previous || shouldRender(previous) || @@ -136,18 +167,55 @@ export const MessageAggregator = ({ }} /> - setJumpToMessage(msg._id)} - css={{ - position: 'relative', - zIndex: 10, - marginRight: '5px', - }} - > - - + {!isStarredMessageDisplay && !isPinnedMessageDisplay && ( + setJumpToMessage(msg._id)} + css={{ + position: 'relative', + zIndex: 10, + marginRight: '5px', + }} + > + + + )} + {(isStarredMessageDisplay || isPinnedMessageDisplay) && ( + + unstar(msg) + : () => unpin(msg), + label: isStarredMessageDisplay + ? 'Remove star' + : 'Unpin', + icon: isStarredMessageDisplay ? 'star' : 'pin', + }, + { + id: 'copyLink', + action: () => copyLink(msg._id), + label: 'Copy link', + icon: 'link', + }, + { + id: 'navigate', + action: () => setJumpToMessage(msg._id), + label: 'Navigate', + icon: 'arrow-back', + }, + ]} + /> + + )} )} diff --git a/packages/react/src/views/MessageAggregators/common/MessageAggregator.styles.js b/packages/react/src/views/MessageAggregators/common/MessageAggregator.styles.js index 1f18222e3e..625e3a0578 100644 --- a/packages/react/src/views/MessageAggregators/common/MessageAggregator.styles.js +++ b/packages/react/src/views/MessageAggregators/common/MessageAggregator.styles.js @@ -9,6 +9,8 @@ const getMessageAggregatorStyles = () => { justify-content: initial; align-items: initial; max-width: 100%; + overflow-y: scroll; + padding-right: 0; `, noMessageStyles: css`