diff --git a/ui/src/components/Sidebar/MessagesSidebarItem.tsx b/ui/src/components/Sidebar/MessagesSidebarItem.tsx
new file mode 100644
index 0000000000..c943cdc076
--- /dev/null
+++ b/ui/src/components/Sidebar/MessagesSidebarItem.tsx
@@ -0,0 +1,51 @@
+import cn from 'classnames';
+import { Link } from 'react-router-dom';
+import useMessagesUnreadCount from '@/logic/useMessagesUnreadCount';
+import MessagesIcon from '../icons/MessagesIcon';
+import SidebarItem from './SidebarItem';
+import useActiveTab from './util';
+import AddIcon16 from '../icons/Add16Icon';
+import ActivityIndicator from './ActivityIndicator';
+
+export default function MessagesSidebarItem() {
+ const activeTab = useActiveTab();
+ const unreadCount = useMessagesUnreadCount();
+
+ return (
+
+ }
+ actions={
+
+ {unreadCount > 0 && (
+
+ )}
+
+
+
+
+ }
+ to={'/messages'}
+ className="group"
+ color={activeTab === 'messages' ? 'text-black' : 'text-gray-600'}
+ >
+ Messages
+
+ );
+}
diff --git a/ui/src/components/Sidebar/SidebarTopMenu.tsx b/ui/src/components/Sidebar/SidebarTopMenu.tsx
index 4b2ad3ec50..a6f3f4b0d9 100644
--- a/ui/src/components/Sidebar/SidebarTopMenu.tsx
+++ b/ui/src/components/Sidebar/SidebarTopMenu.tsx
@@ -1,21 +1,14 @@
import React, { useContext } from 'react';
-import cn from 'classnames';
-import { debounce } from 'lodash';
-import { Link, useLocation } from 'react-router-dom';
-import ActivityIndicator, {
- ActivitySidebarItem,
-} from '@/components/Sidebar/ActivityIndicator';
-import { useIsMobile } from '@/logic/useMedia';
+import { ActivitySidebarItem } from '@/components/Sidebar/ActivityIndicator';
import SidebarItem from '@/components/Sidebar/SidebarItem';
import { AppUpdateContext } from '@/logic/useAppUpdates';
import ShipName from '@/components/ShipName';
import Avatar, { useProfileColor } from '@/components/Avatar';
import AddGroupSidebarItem from './AddGroupSidebarItem';
import SidebarHeader from './SidebarHeader';
-import MessagesIcon from '../icons/MessagesIcon';
import { DesktopUpdateButton } from '../UpdateNotices';
import useActiveTab from './util';
-import AddIcon16 from '../icons/Add16Icon';
+import MessagesSidebarItem from './MessagesSidebarItem';
const UpdateOrAppMenu = React.memo(() => {
const { needsUpdate } = useContext(AppUpdateContext);
@@ -31,30 +24,7 @@ const SidebarTopMenu = React.memo(() => {
-
-
- }
- actions={
-
-
-
- }
- to={'/messages'}
- className="group"
- color={activeTab === 'messages' ? 'text-black' : 'text-gray-600'}
- >
- Messages
-
-
+
+ Object.entries(dmUnreads).reduce(
+ (acc, [_whom, unread]) => (unread.count > 0 ? acc + 1 : acc),
+ 0
+ ),
+ [dmUnreads]
+ );
+ const chatChannelUnreadsCount = useMemo(
+ () =>
+ Object.entries(channelUnreads).reduce(
+ (acc, [channel, unread]) =>
+ unread.count > 0 && channel.includes('chat/') ? acc + 1 : acc,
+ 0
+ ),
+ [channelUnreads]
+ );
+
+ const pinnedDmUnreadsCount = useMemo(
+ () =>
+ pins
+ .filter((pin) => whomIsDm(pin) || whomIsMultiDm(pin))
+ .reduce((accum, whom) => {
+ const unread = dmUnreads[whom];
+ return unread.count > 0 ? accum + 1 : accum;
+ }, 0),
+ [pins, dmUnreads]
+ );
+
+ const pinnedChatUnreadsCount = useMemo(
+ () =>
+ pins
+ .filter((pin) => whomIsNest(pin))
+ .reduce((accum, whom) => {
+ const unread = dmUnreads[whom];
+ return unread.count > 0 ? accum + 1 : accum;
+ }, 0),
+ [pins, dmUnreads]
+ );
+
+ const unreadCount = useMemo(() => {
+ switch (messagesFilter) {
+ case 'All Messages':
+ return dmUnreadsCount + chatChannelUnreadsCount;
+ case 'Group Channels':
+ return chatChannelUnreadsCount + pinnedDmUnreadsCount;
+ case 'Direct Messages':
+ default:
+ return dmUnreadsCount + pinnedChatUnreadsCount;
+ }
+ }, [
+ messagesFilter,
+ dmUnreadsCount,
+ chatChannelUnreadsCount,
+ pinnedDmUnreadsCount,
+ pinnedChatUnreadsCount,
+ ]);
+
+ return unreadCount;
+}