Skip to content

Commit

Permalink
Change pinned and starred message windows to sidebars (#501)
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffreytheCoder authored Mar 21, 2024
1 parent 166f36e commit 63e0523
Show file tree
Hide file tree
Showing 9 changed files with 342 additions and 10 deletions.
20 changes: 10 additions & 10 deletions packages/react/src/components/ChatHeader/ChatHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
useToastStore,
useThreadsMessageStore,
useMentionsStore,
usePinnedMessageStore,
useStarredMessageStore,
useFileStore,
} from '../../store';
import { DynamicHeader } from '../DynamicHeader';
Expand Down Expand Up @@ -72,6 +74,10 @@ const ChatHeader = ({
const toggleShowMembers = useMemberStore((state) => state.toggleShowMembers);
const showMembers = useMemberStore((state) => state.showMembers);
const setShowSearch = useSearchMessageStore((state) => state.setShowSearch);
const setShowPinned = usePinnedMessageStore((state) => state.setShowPinned);
const setShowStarred = useStarredMessageStore(
(state) => state.setShowStarred
);
const setShowAllThreads = useThreadsMessageStore(
(state) => state.setShowAllThreads
);
Expand Down Expand Up @@ -101,18 +107,12 @@ const ChatHeader = ({
}, [RCInstance, setIsUserAuthenticated]);

const showStarredMessage = useCallback(async () => {
const { messages } = await RCInstance.getStarredMessages();
setMessages(messages);
setHeaderTitle('Starred Messages');
setFilter(true);
}, [RCInstance, setMessages, setHeaderTitle, setFilter]);
setShowStarred(true);
}, [RCInstance, setShowStarred]);

const showPinnedMessage = useCallback(async () => {
const { messages } = await RCInstance.getPinnedMessages();
setMessages(messages);
setHeaderTitle('Pinned Messages');
setFilter(true);
}, [RCInstance, setMessages, setHeaderTitle, setFilter]);
setShowPinned(true);
}, [RCInstance, setShowPinned]);

const showChannelMembers = useCallback(async () => {
const { members = [] } = await RCInstance.getChannelMembers(
Expand Down
8 changes: 8 additions & 0 deletions packages/react/src/components/MessageList/MessageList.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
useFileStore,
useMentionsStore,
useThreadsMessageStore,
usePinnedMessageStore,
useStarredMessageStore,
} from '../../store';
import RoomMembers from '../RoomMembers/RoomMember';
import MessageReportWindow from '../ReportMessage/MessageReportWindow';
Expand All @@ -20,6 +22,8 @@ import Roominfo from '../RoomInformation/RoomInformation';
import AllThreads from '../AllThreads/AllThreads';
import { Files } from '../Files';
import { Message } from '../Message';
import PinnedMessages from '../PinnedMessages/PinnedMessages';
import StarredMessages from '../StarredMessages/StarredMessages';
import { Icon } from '../Icon';

const MessageList = ({ messages }) => {
Expand All @@ -36,6 +40,8 @@ const MessageList = ({ messages }) => {
const showAllThreads = useThreadsMessageStore(
(state) => state.showAllThreads
);
const showPinned = usePinnedMessageStore((state) => state.showPinned);
const showStarred = useStarredMessageStore((state) => state.showStarred);

const isMessageNewDay = (current, previous) =>
!previous || !isSameDay(new Date(current.ts), new Date(previous.ts));
Expand Down Expand Up @@ -86,6 +92,8 @@ const MessageList = ({ messages }) => {
{showAllThreads && <AllThreads />}
{showAllFiles && <Files />}
{showMentions && <UserMentions />}
{showPinned && <PinnedMessages />}
{showStarred && <StarredMessages />}
</>
);
};
Expand Down
129 changes: 129 additions & 0 deletions packages/react/src/components/PinnedMessages/PinnedMessages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import React, { useState, useContext, useMemo, useEffect } from 'react';
import { isSameDay, format } from 'date-fns';
import RCContext from '../../context/RCInstance';
import classes from './PinnedMessages.module.css';
import { usePinnedMessageStore } from '../../store';
import { Box } from '../Box';
import { Icon } from '../Icon';
import { ActionButton } from '../ActionButton';
import { MessageDivider } from '../Message/MessageDivider';
import { Message } from '../Message';
import isMessageSequential from '../../lib/isMessageSequential';
import { Throbber } from '../Throbber';

const PinnedMessages = () => {
const { RCInstance } = useContext(RCContext);
const setShowPinned = usePinnedMessageStore((state) => state.setShowPinned);

const [messageList, setMessageList] = useState([]);
const [loading, setLoading] = useState(true);

const toggleShowPinned = () => {
setShowPinned(false);
};

const getPinnedMessages = async () => {
const { messages } = await RCInstance.getPinnedMessages();
setMessageList(messages);
setLoading(false);
};

useEffect(() => {
if (messageList.length === 0) {
getPinnedMessages();
}
}, [messageList, getPinnedMessages]);

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

return (
<Box className={classes.sidebar} style={{ padding: '1rem' }}>
<Box className={classes.wrapContainer}>
<Box
style={{
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
gap: '0.5rem',
marginBottom: '1rem',
}}
>
<h3 style={{ display: 'contents' }}>
<Icon name="pin" size="1.25rem" />
<Box style={{ color: '#4a4a4a', width: '80%' }}>
Pinned Messages
</Box>
<ActionButton onClick={toggleShowPinned} ghost size="small">
<Icon name="cross" size="x20" />
</ActionButton>
</h3>
</Box>
<Box
style={{
flex: '1',
overflow: 'auto',
display: 'flex',
flexDirection: 'column',
justifyContent: messageList.length === 0 ? 'center' : 'initial',
alignItems: messageList.length === 0 ? 'center' : 'initial',
}}
>
{loading ? (
<Box
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
color: '#4a4a4a',
}}
>
<Throbber />
</Box>
) : messageList.length === 0 ? (
<Box
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
color: '#4a4a4a',
}}
>
<Icon name="pin" size="3rem" style={{ padding: '0.5rem' }} />
<span style={{ fontSize: '1.2rem', fontWeight: 'bold' }}>
No pinned messages
</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={sequential}
variant="default"
showAvatar
showToolbox={false}
/>
</Box>
);
})
)}
</Box>
</Box>
</Box>
);
};
export default PinnedMessages;
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.sidebar {
position: fixed;
right: 0;
top: 0;
width: 350px;
height: 100%;
overflow-x: scroll;
overflow-y: scroll;
background-color: white;
box-shadow: -1px 0px 5px rgb(0 0 0 / 25%);
z-index: 100;
}

.wrapContainer {
height: 100%;
display: flex;
flex-direction: column;
}
@media (max-width: 550px) {
.sidebar {
width: 100vw;
}
}
131 changes: 131 additions & 0 deletions packages/react/src/components/StarredMessages/StarredMessages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import React, { useState, useContext, useMemo, useEffect } from 'react';
import { isSameDay, format } from 'date-fns';
import RCContext from '../../context/RCInstance';
import classes from './StarredMessages.module.css';
import { useStarredMessageStore } from '../../store';
import { Box } from '../Box';
import { Icon } from '../Icon';
import { ActionButton } from '../ActionButton';
import { MessageDivider } from '../Message/MessageDivider';
import { Message } from '../Message';
import isMessageSequential from '../../lib/isMessageSequential';
import { Throbber } from '../Throbber';

const StarredMessages = () => {
const { RCInstance } = useContext(RCContext);
const setShowStarred = useStarredMessageStore(
(state) => state.setShowStarred
);

const [messageList, setMessageList] = useState([]);
const [loading, setLoading] = useState(true);

const toggleShowStarred = () => {
setShowStarred(false);
};

const getStarredMessages = async () => {
const { messages } = await RCInstance.getStarredMessages();
setMessageList(messages);
setLoading(false);
};

useEffect(() => {
if (messageList.length === 0) {
getStarredMessages();
}
}, [messageList, getStarredMessages]);

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

return (
<Box className={classes.sidebar} style={{ padding: '1rem' }}>
<Box className={classes.wrapContainer}>
<Box
style={{
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
gap: '0.5rem',
marginBottom: '1rem',
}}
>
<h3 style={{ display: 'contents' }}>
<Icon name="star" size="1.25rem" />
<Box style={{ color: '#4a4a4a', width: '80%' }}>
Starred Messages
</Box>
<ActionButton onClick={toggleShowStarred} ghost size="small">
<Icon name="cross" size="x20" />
</ActionButton>
</h3>
</Box>
<Box
style={{
flex: '1',
overflow: 'auto',
display: 'flex',
flexDirection: 'column',
justifyContent: messageList.length === 0 ? 'center' : 'initial',
alignItems: messageList.length === 0 ? 'center' : 'initial',
}}
>
{loading ? (
<Box
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
color: '#4a4a4a',
}}
>
<Throbber />
</Box>
) : messageList.length === 0 ? (
<Box
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
color: '#4a4a4a',
}}
>
<Icon name="star" size="3rem" style={{ padding: '0.5rem' }} />
<span style={{ fontSize: '1.2rem', fontWeight: 'bold' }}>
No starred messages
</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={sequential}
variant="default"
showAvatar
showToolbox={false}
/>
</Box>
);
})
)}
</Box>
</Box>
</Box>
);
};
export default StarredMessages;
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.sidebar {
position: fixed;
right: 0;
top: 0;
width: 350px;
height: 100%;
overflow-x: scroll;
overflow-y: scroll;
background-color: white;
box-shadow: -1px 0px 5px rgb(0 0 0 / 25%);
z-index: 100;
}

.wrapContainer {
height: 100%;
display: flex;
flex-direction: column;
}
@media (max-width: 550px) {
.sidebar {
width: 100vw;
}
}
2 changes: 2 additions & 0 deletions packages/react/src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ export { default as useChannelStore } from './channelStore';
export { default as useThreadsMessageStore } from './threadsMessageStore';
export { default as useFileStore } from './fileStore';
export { default as useMentionsStore } from './mentionsStore';
export { default as usePinnedMessageStore } from './pinnedMessageStore';
export { default as useStarredMessageStore } from './starredMessageStore';
Loading

0 comments on commit 63e0523

Please sign in to comment.