From 94c37ea144083db393918fb5e65a0001036dd492 Mon Sep 17 00:00:00 2001
From: Jeffrey Yu <35394596+JeffreytheCoder@users.noreply.github.com>
Date: Thu, 7 Mar 2024 12:19:22 -0800
Subject: [PATCH] Change pinned and starred message windows to sidebars
---
.../src/components/ChatHeader/ChatHeader.js | 20 +--
.../src/components/MessageList/MessageList.js | 8 ++
.../PinnedMessages/PinnedMessages.js | 129 +++++++++++++++++
.../PinnedMessages/PinnedMessages.module.css | 23 +++
.../StarredMessages/StarredMessages.js | 131 ++++++++++++++++++
.../StarredMessages.module.css | 23 +++
packages/react/src/store/index.js | 2 +
.../react/src/store/pinnedMessageStore.js | 8 ++
.../react/src/store/starredMessageStore.js | 8 ++
9 files changed, 342 insertions(+), 10 deletions(-)
create mode 100644 packages/react/src/components/PinnedMessages/PinnedMessages.js
create mode 100644 packages/react/src/components/PinnedMessages/PinnedMessages.module.css
create mode 100644 packages/react/src/components/StarredMessages/StarredMessages.js
create mode 100644 packages/react/src/components/StarredMessages/StarredMessages.module.css
create mode 100644 packages/react/src/store/pinnedMessageStore.js
create mode 100644 packages/react/src/store/starredMessageStore.js
diff --git a/packages/react/src/components/ChatHeader/ChatHeader.js b/packages/react/src/components/ChatHeader/ChatHeader.js
index 08cfdc8bd..fdad23ed6 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,
} from '../../store';
import { DynamicHeader } from '../DynamicHeader';
import { Tooltip } from '../Tooltip';
@@ -71,6 +73,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
);
@@ -99,18 +105,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 2cad03c4d..0a7d30fc7 100644
--- a/packages/react/src/components/MessageList/MessageList.js
+++ b/packages/react/src/components/MessageList/MessageList.js
@@ -9,6 +9,8 @@ import {
useUserStore,
useMentionsStore,
useThreadsMessageStore,
+ usePinnedMessageStore,
+ useStarredMessageStore,
} from '../../store';
import RoomMembers from '../RoomMembers/RoomMember';
import MessageReportWindow from '../ReportMessage/MessageReportWindow';
@@ -18,6 +20,8 @@ import Roominfo from '../RoomInformation/RoomInformation';
import AllThreads from '../AllThreads/AllThreads';
import UserMentions from '../UserMentions/UserMentions';
import { Message } from '../Message';
+import PinnedMessages from '../PinnedMessages/PinnedMessages';
+import StarredMessages from '../StarredMessages/StarredMessages';
const MessageList = ({ messages }) => {
const showSearch = useSearchMessageStore((state) => state.showSearch);
@@ -31,6 +35,8 @@ const MessageList = ({ messages }) => {
(state) => state.showAllThreads
);
const showMentions = useMentionsStore((state) => state.showMentions);
+ 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));
@@ -62,6 +68,8 @@ const MessageList = ({ messages }) => {
{showChannelinfo && }
{showAllThreads && }
{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 78da56784..7c925f67d 100644
--- a/packages/react/src/store/index.js
+++ b/packages/react/src/store/index.js
@@ -8,3 +8,5 @@ export { default as loginModalStore } from './loginmodalStore';
export { default as useChannelStore } from './channelStore';
export { default as useThreadsMessageStore } from './threadsMessageStore';
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;