Skip to content

Commit

Permalink
Make search tab consistent with threads & RC (#497)
Browse files Browse the repository at this point in the history
* Make search tab consistent with threads & RC

* Fix linting errors
  • Loading branch information
JeffreytheCoder authored Mar 8, 2024
1 parent 29bf9ca commit 94d2222
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 72 deletions.
3 changes: 2 additions & 1 deletion packages/react/src/components/Message/Message.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const Message = ({
showAvatar = false,
className = '',
style = {},
showToolbox = true,
}) => {
const { classNames, styleOverrides } = useComponentOverrides(
'Message',
Expand Down Expand Up @@ -215,7 +216,7 @@ const Message = ({
handleOpenThread={handleOpenThread}
/>
) : null}
{!message.t ? (
{!message.t && showToolbox ? (
<MessageToolbox
message={message}
isEditing={editMessage._id === message._id}
Expand Down
188 changes: 117 additions & 71 deletions packages/react/src/components/SearchMessage/SearchMessage.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
import React, { useState, useContext } from 'react';
import React, { useState, useContext, useMemo, useEffect } from 'react';
import { isSameDay, format } from 'date-fns';
import { debounce } from 'lodash';
import RCContext from '../../context/RCInstance';
import classes from './SearchMessage.module.css';
import { Markdown } from '../Markdown/index';
import { useUserStore, useSearchMessageStore } from '../../store';
import { Button } from '../Button';
import { Box } from '../Box';
import { Icon } from '../Icon';
import { ActionButton } from '../ActionButton';
import { MessageContainer } from '../Message/MessageContainer';
import { MessageDivider } from '../Message/MessageDivider';
import { MessageReactions } from '../Message/MessageReactions';
import MessageHeader from '../Message/MessageHeader';
import { MessageBody } from '../Message/MessageBody';
import MessageBodyContainer from '../Message/MessageBodyContainer';
import { Message } from '../Message';
import isMessageSequential from '../../lib/isMessageSequential';

const Search = () => {
const { RCInstance } = useContext(RCContext);
const setShowSearch = useSearchMessageStore((state) => state.setShowSearch);
const authenticatedUserUsername = useUserStore((state) => state.username);

const toggleShowSearch = () => {
setShowSearch(false);
Expand All @@ -27,83 +22,134 @@ const Search = () => {
const [text, setText] = useState('');
const [messageList, setMessageList] = useState([]);

const handleInputChange = (e) => {
setText(e.target.value);
};

const searchMessages = async () => {
const { messages } = await RCInstance.getSearchMessages(text);
setMessageList(messages);
};

const handleKeyPress = (e) => {
if (e.key === 'Enter') {
searchMessages();
const debouncedSearch = debounce(async () => {
await searchMessages();
}, 500); // 500ms delay

useEffect(() => {
if (!text.trim()) {
setMessageList([]);
} else {
debouncedSearch();
}
};

// Cleanup function to cancel the debounce on component unmount
return () => {
debouncedSearch.cancel();
};
}, [text, debouncedSearch]);

const isMessageNewDay = (current, previous) =>
!previous || !isSameDay(new Date(current.ts), new Date(previous.ts));

return (
<Box className={classes.searchBar} style={{ padding: '1rem' }}>
<Box
style={{
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
gap: '0.5rem',
marginBottom: '1rem',
}}
>
<h3 style={{ display: 'contents' }}>
<Icon name="magnifier" size="1.25rem" />
<Box style={{ color: '#4a4a4a', width: '80%' }}>Search Messages</Box>
<ActionButton onClick={toggleShowSearch} ghost size="small">
<Icon name="cross" size="x20" />
</ActionButton>
</h3>
</Box>
<Box
className={classes.container}
style={{ border: '2px solid #ddd', position: 'relative' }}
>
<input
placeholder="Search Message"
onChange={(e) => setText(e.target.value)}
onKeyDown={handleKeyPress}
className={classes.textInput}
/>
<Box className={classes.wrapContainer}>
<Box
style={{
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
gap: '0.5rem',
marginBottom: '1rem',
}}
>
<h3 style={{ display: 'contents' }}>
<Icon name="magnifier" size="1.25rem" />
<Box style={{ color: '#4a4a4a', width: '80%' }}>
Search Messages
</Box>
<ActionButton onClick={toggleShowSearch} ghost size="small">
<Icon name="cross" size="x20" />
</ActionButton>
</h3>
</Box>
<Box
className={classes.container}
style={{
border: '2px solid #ddd',
position: 'relative',
marginBottom: '1rem',
}}
>
<input
placeholder="Search Message"
onChange={handleInputChange}
className={classes.textInput}
/>

<Icon
name="magnifier"
size="1.25rem"
style={{ padding: '0.125em', cursor: 'pointer' }}
onClick={searchMessages}
/>
</Box>
{messageList &&
messageList.map((msg, index, arr) => {
const prev = arr[index + 1];
const newDay = isMessageNewDay(msg, prev);
return (
<React.Fragment key={msg._id}>
{newDay && (
<MessageDivider>
{format(new Date(msg.ts), 'MMMM d, yyyy')}
</MessageDivider>
)}
<MessageContainer>
<MessageBodyContainer>
<MessageHeader message={msg} />
<MessageBody>
<Markdown body={msg} />
</MessageBody>
<MessageReactions
authenticatedUserUsername={authenticatedUserUsername}
<Icon
name="magnifier"
size="1.25rem"
style={{ padding: '0.125em', cursor: 'pointer' }}
/>
</Box>
<Box
style={{
flex: '1',
overflow: 'auto',
display: 'flex',
flexDirection: 'column',
justifyContent: messageList.length === 0 ? 'center' : 'initial',
alignItems: messageList.length === 0 ? 'center' : 'initial',
}}
>
{messageList.length === 0 ? (
<Box
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
color: '#4a4a4a',
}}
>
<Icon
name="magnifier"
size="3rem"
style={{ padding: '0.5rem' }}
/>
<span style={{ fontSize: '1.2rem', fontWeight: 'bold' }}>
No results found
</span>
</Box>
) : (
messageList.map((msg, index, arr) => {
const prev = arr[index + 1];
const newDay = isMessageNewDay(msg, prev);
const sequential = isMessageSequential(msg, prev, 300);
return (
<Box key={msg._id}>
{newDay && (
<Box style={{ paddingTop: '0.5rem' }}>
<MessageDivider>
{format(new Date(msg.ts), 'MMMM d, yyyy')}
</MessageDivider>
</Box>
)}
<Message
key={msg._id}
message={msg}
newDay={false}
sequential={false}
variant="default"
showAvatar
showToolbox={false}
/>
</MessageBodyContainer>
</MessageContainer>
</React.Fragment>
);
})}
</Box>
);
})
)}
</Box>
</Box>
</Box>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
z-index: 100;
}

.wrapContainer {
height: 100%;
display: flex;
flex-direction: column;
}

.container {
display: flex;
align-items: center;
Expand Down

0 comments on commit 94d2222

Please sign in to comment.