Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

desktop nav: display unread count on messages tab #3223

Merged
merged 4 commits into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions ui/src/components/Sidebar/MessagesSidebarItem.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<SidebarItem
icon={
<MessagesIcon
className={cn(
'm-1 h-4 w-4',
activeTab === 'messages' && 'text-black'
)}
nonNav
isInactive={activeTab !== 'messages'}
/>
}
actions={
<div className="group">
{unreadCount > 0 && (
<ActivityIndicator
count={unreadCount}
className="group-hover:hidden"
bg={
activeTab === 'messages'
? 'bg-none text-black'
: 'bg-blue-soft text-blue'
}
/>
)}
<Link to="/dm/new" className="hidden items-center group-hover:flex">
<AddIcon16 className="h-4 w-4" />
</Link>
</div>
}
to={'/messages'}
className="group"
color={activeTab === 'messages' ? 'text-black' : 'text-gray-600'}
>
Messages
</SidebarItem>
);
}
36 changes: 3 additions & 33 deletions ui/src/components/Sidebar/SidebarTopMenu.tsx
Original file line number Diff line number Diff line change
@@ -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);
Expand All @@ -31,30 +24,7 @@ const SidebarTopMenu = React.memo(() => {
<UpdateOrAppMenu />

<AddGroupSidebarItem />

<SidebarItem
icon={
<MessagesIcon
className={cn(
'm-1 h-4 w-4',
activeTab === 'messages' && 'text-black'
)}
nonNav
isInactive={activeTab !== 'messages'}
/>
}
actions={
<Link to="/dm/new" className="hidden group-hover:block">
<AddIcon16 className="h-4 w-4" />
</Link>
}
to={'/messages'}
className="group"
color={activeTab === 'messages' ? 'text-black' : 'text-gray-600'}
>
Messages
</SidebarItem>

<MessagesSidebarItem />
<ActivitySidebarItem />

<SidebarItem
Expand Down
73 changes: 73 additions & 0 deletions ui/src/logic/useMessagesUnreadCount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { useMemo } from 'react';
import { useDmUnreads } from '@/state/chat';
import { useUnreads } from '@/state/channel/channel';
import { useMessagesFilter } from '@/state/settings';
import { usePinnedChats } from '@/state/pins';
import { whomIsDm, whomIsMultiDm, whomIsNest } from '@/logic/utils';

export default function useMessagesUnreadCount(): number {
const { data: dmUnreads } = useDmUnreads();
const channelUnreads = useUnreads();
const messagesFilter = useMessagesFilter();
const pins = usePinnedChats();

const dmUnreadsCount = useMemo(
() =>
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;
}
Loading