From 2858b8c157867e6228b4c4e4d4943518712bcf98 Mon Sep 17 00:00:00 2001 From: Anirban Singha Date: Tue, 24 Dec 2024 15:15:04 +0530 Subject: [PATCH 1/2] feat: enable navigation from files list to corresponding messages in chat body --- .../src/views/FileMessage/FileMessage.js | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/packages/react/src/views/FileMessage/FileMessage.js b/packages/react/src/views/FileMessage/FileMessage.js index a074e981ef..6d3d06bee0 100644 --- a/packages/react/src/views/FileMessage/FileMessage.js +++ b/packages/react/src/views/FileMessage/FileMessage.js @@ -17,7 +17,7 @@ import FilePreviewHeader from './FilePreviewHeader'; import { MessageBody as FileBody } from '../Message/MessageBody'; import { FileMetrics } from './FileMetrics'; import { useRCContext } from '../../context/RCInstance'; -import { useMessageStore } from '../../store'; +import { useMessageStore, useSidebarStore } from '../../store'; import { fileDisplayStyles as styles } from './Files.styles'; const FileMessage = ({ fileMessage }) => { @@ -25,6 +25,7 @@ const FileMessage = ({ fileMessage }) => { const dispatchToastMessage = useToastBarDispatch(); const { RCInstance } = useRCContext(); const messages = useMessageStore((state) => state.messages); + const setShowSidebar = useSidebarStore((state) => state.setShowSidebar); const [fileToDelete, setFileToDelete] = useState({}); @@ -37,6 +38,23 @@ const FileMessage = ({ fileMessage }) => { document.body.removeChild(anchor); }, []); + const navigateToFile = (id) => { + const message = messages.find((msg) => msg?.file?._id === id); + if (message) { + const element = document.getElementById(`ec-message-body-${message._id}`); + if (element) { + element.style.backgroundColor = '#ffeb3b'; + element.scrollIntoView({ behavior: 'smooth', block: 'center' }); + setShowSidebar(false); + + setTimeout(() => { + element.style.backgroundColor = ''; + element.style.transition = 'background-color 0.5s ease-out'; + }, 2000); + } + } + }; + const deleteFile = useCallback( async (file) => { messages.forEach(async (message) => { @@ -92,10 +110,16 @@ const FileMessage = ({ fileMessage }) => { }, { id: 'delete', - action: () => setFileToDelete(fileMessage), + action: () => setFileToDelete(fileMessage._id), label: 'Delete', icon: 'trash', }, + { + id: 'navigate', + action: () => navigateToFile(fileMessage._id), + label: 'Navigate', + icon: 'arrow-back', + }, ]} /> From 5bb3d61b065c26303b34fae7373efaa93cac71a8 Mon Sep 17 00:00:00 2001 From: Anirban Singha Date: Sat, 11 Jan 2025 02:37:23 +0530 Subject: [PATCH 2/2] revised changes --- .../src/views/FileMessage/FileMessage.js | 53 +++++++++++++------ .../src/components/Icon/icons/ArrowJump.js | 9 ++++ .../src/components/Icon/icons/index.js | 2 + 3 files changed, 48 insertions(+), 16 deletions(-) create mode 100644 packages/ui-elements/src/components/Icon/icons/ArrowJump.js diff --git a/packages/react/src/views/FileMessage/FileMessage.js b/packages/react/src/views/FileMessage/FileMessage.js index 6d3d06bee0..ff433f74d0 100644 --- a/packages/react/src/views/FileMessage/FileMessage.js +++ b/packages/react/src/views/FileMessage/FileMessage.js @@ -6,9 +6,12 @@ import { Modal, Button, Icon, + useTheme, useToastBarDispatch, useComponentOverrides, appendClassNames, + lighten, + darken, } from '@embeddedchat/ui-elements'; import FilePreviewContainer from './FilePreviewContainer'; import FileBodyContainer from '../Message/MessageBodyContainer'; @@ -26,6 +29,8 @@ const FileMessage = ({ fileMessage }) => { const { RCInstance } = useRCContext(); const messages = useMessageStore((state) => state.messages); const setShowSidebar = useSidebarStore((state) => state.setShowSidebar); + const { theme } = useTheme(); + const { mode } = useTheme(); const [fileToDelete, setFileToDelete] = useState({}); @@ -38,20 +43,36 @@ const FileMessage = ({ fileMessage }) => { document.body.removeChild(anchor); }, []); - const navigateToFile = (id) => { - const message = messages.find((msg) => msg?.file?._id === id); + const navigateToFile = (msg) => { + if (!msg || !msg._id) { + console.error('Invalid message object:', msg); + return; + } + + const message = messages.find((mg) => mg?.file?._id === msg._id); + if (message) { - const element = document.getElementById(`ec-message-body-${message._id}`); - if (element) { - element.style.backgroundColor = '#ffeb3b'; - element.scrollIntoView({ behavior: 'smooth', block: 'center' }); - setShowSidebar(false); - - setTimeout(() => { - element.style.backgroundColor = ''; - element.style.transition = 'background-color 0.5s ease-out'; - }, 2000); - } + let element; + setTimeout(() => { + const childElement = document.getElementById( + `ec-message-body-${message._id}` + ); + element = childElement.closest('.ec-message'); + + if (element) { + setShowSidebar(false); + element.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); + + element.style.backgroundColor = + mode === 'light' + ? darken(theme.colors.warning, 0.03) + : lighten(theme.colors.warningForeground, 0.03); + + setTimeout(() => { + element.style.backgroundColor = ''; + }, 2000); + } + }, 300); } }; @@ -116,9 +137,9 @@ const FileMessage = ({ fileMessage }) => { }, { id: 'navigate', - action: () => navigateToFile(fileMessage._id), - label: 'Navigate', - icon: 'arrow-back', + action: () => navigateToFile(fileMessage), + label: 'Jump to message', + icon: 'arrow-jump', }, ]} /> diff --git a/packages/ui-elements/src/components/Icon/icons/ArrowJump.js b/packages/ui-elements/src/components/Icon/icons/ArrowJump.js new file mode 100644 index 0000000000..17e69514b9 --- /dev/null +++ b/packages/ui-elements/src/components/Icon/icons/ArrowJump.js @@ -0,0 +1,9 @@ +import React from 'react'; + +const ArrowJump = (props) => ( + + + +); + +export default ArrowJump; diff --git a/packages/ui-elements/src/components/Icon/icons/index.js b/packages/ui-elements/src/components/Icon/icons/index.js index 77cd6a4511..f348ba0673 100644 --- a/packages/ui-elements/src/components/Icon/icons/index.js +++ b/packages/ui-elements/src/components/Icon/icons/index.js @@ -61,6 +61,7 @@ import Arc from './Arc'; import Avatar from './Avatar'; import FormatText from './FormatText'; import Cog from './Cog'; +import ArrowJump from './ArrowJump'; const icons = { file: File, @@ -126,6 +127,7 @@ const icons = { avatar: Avatar, 'format-text': FormatText, cog: Cog, + 'arrow-jump': ArrowJump, }; export default icons;