diff --git a/packages/react/src/components/ChatHeader/ChatHeader.js b/packages/react/src/components/ChatHeader/ChatHeader.js
index 8b9392196..ff9ee4827 100644
--- a/packages/react/src/components/ChatHeader/ChatHeader.js
+++ b/packages/react/src/components/ChatHeader/ChatHeader.js
@@ -12,6 +12,8 @@ import {
useToastStore,
useThreadsMessageStore,
useMentionsStore,
+ usePinnedMessageStore,
+ useStarredMessageStore,
useFileStore,
} from '../../store';
import { DynamicHeader } from '../DynamicHeader';
@@ -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
);
@@ -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(
diff --git a/packages/react/src/components/MessageList/MessageList.js b/packages/react/src/components/MessageList/MessageList.js
index 14bf6fc63..c33f80555 100644
--- a/packages/react/src/components/MessageList/MessageList.js
+++ b/packages/react/src/components/MessageList/MessageList.js
@@ -10,6 +10,8 @@ import {
useFileStore,
useMentionsStore,
useThreadsMessageStore,
+ usePinnedMessageStore,
+ useStarredMessageStore,
} from '../../store';
import RoomMembers from '../RoomMembers/RoomMember';
import MessageReportWindow from '../ReportMessage/MessageReportWindow';
@@ -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 }) => {
@@ -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));
@@ -86,6 +92,8 @@ const MessageList = ({ messages }) => {
{showAllThreads && }
{showAllFiles && }
{showMentions && }
+ {showPinned && }
+ {showStarred && }
>
);
};
diff --git a/packages/react/src/components/PinnedMessages/PinnedMessages.js b/packages/react/src/components/PinnedMessages/PinnedMessages.js
new file mode 100644
index 000000000..409fce044
--- /dev/null
+++ b/packages/react/src/components/PinnedMessages/PinnedMessages.js
@@ -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 (
+
+
+
+
+
+
+ Pinned Messages
+
+
+
+
+
+
+
+ {loading ? (
+
+
+
+ ) : messageList.length === 0 ? (
+
+
+
+ No pinned messages
+
+
+ ) : (
+ messageList.map((msg, index, arr) => {
+ const prev = arr[index + 1];
+ const newDay = isMessageNewDay(msg, prev);
+ const sequential = isMessageSequential(msg, prev, 300);
+ return (
+
+ {newDay && (
+
+
+ {format(new Date(msg.ts), 'MMMM d, yyyy')}
+
+
+ )}
+
+
+ );
+ })
+ )}
+
+
+
+ );
+};
+export default PinnedMessages;
diff --git a/packages/react/src/components/PinnedMessages/PinnedMessages.module.css b/packages/react/src/components/PinnedMessages/PinnedMessages.module.css
new file mode 100644
index 000000000..d8eba8916
--- /dev/null
+++ b/packages/react/src/components/PinnedMessages/PinnedMessages.module.css
@@ -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;
+ }
+}
diff --git a/packages/react/src/components/StarredMessages/StarredMessages.js b/packages/react/src/components/StarredMessages/StarredMessages.js
new file mode 100644
index 000000000..28be5f148
--- /dev/null
+++ b/packages/react/src/components/StarredMessages/StarredMessages.js
@@ -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 (
+
+
+
+
+
+
+ Starred Messages
+
+
+
+
+
+
+
+ {loading ? (
+
+
+
+ ) : messageList.length === 0 ? (
+
+
+
+ No starred messages
+
+
+ ) : (
+ messageList.map((msg, index, arr) => {
+ const prev = arr[index + 1];
+ const newDay = isMessageNewDay(msg, prev);
+ const sequential = isMessageSequential(msg, prev, 300);
+ return (
+
+ {newDay && (
+
+
+ {format(new Date(msg.ts), 'MMMM d, yyyy')}
+
+
+ )}
+
+
+ );
+ })
+ )}
+
+
+
+ );
+};
+export default StarredMessages;
diff --git a/packages/react/src/components/StarredMessages/StarredMessages.module.css b/packages/react/src/components/StarredMessages/StarredMessages.module.css
new file mode 100644
index 000000000..d8eba8916
--- /dev/null
+++ b/packages/react/src/components/StarredMessages/StarredMessages.module.css
@@ -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;
+ }
+}
diff --git a/packages/react/src/store/index.js b/packages/react/src/store/index.js
index 9fd11e4c3..c9a8cbf03 100644
--- a/packages/react/src/store/index.js
+++ b/packages/react/src/store/index.js
@@ -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';
diff --git a/packages/react/src/store/pinnedMessageStore.js b/packages/react/src/store/pinnedMessageStore.js
new file mode 100644
index 000000000..36ee4e385
--- /dev/null
+++ b/packages/react/src/store/pinnedMessageStore.js
@@ -0,0 +1,8 @@
+import { create } from 'zustand';
+
+const usePinnedMessageStore = create((set) => ({
+ showPinned: false,
+ setShowPinned: (showPinned) => set(() => ({ showPinned })),
+}));
+
+export default usePinnedMessageStore;
diff --git a/packages/react/src/store/starredMessageStore.js b/packages/react/src/store/starredMessageStore.js
new file mode 100644
index 000000000..a564df3c4
--- /dev/null
+++ b/packages/react/src/store/starredMessageStore.js
@@ -0,0 +1,8 @@
+import { create } from 'zustand';
+
+const useStarredMessageStore = create((set) => ({
+ showStarred: false,
+ setShowStarred: (showStarred) => set(() => ({ showStarred })),
+}));
+
+export default useStarredMessageStore;