From 91a6d1ef5da75c1fed9dc90883b66a64995103d3 Mon Sep 17 00:00:00 2001 From: Ian Philips Date: Wed, 3 Aug 2022 13:26:31 -0600 Subject: [PATCH] Show chat bubble on nav with unseen notifs --- web/components/groups/group-chat.tsx | 77 +++++++++++++++++----------- web/components/nav/sidebar.tsx | 43 ++++++++++------ 2 files changed, 74 insertions(+), 46 deletions(-) diff --git a/web/components/groups/group-chat.tsx b/web/components/groups/group-chat.tsx index a5ccbea8..f5e545ed 100644 --- a/web/components/groups/group-chat.tsx +++ b/web/components/groups/group-chat.tsx @@ -25,6 +25,7 @@ import { formatMoney } from 'common/util/format' import { useWindowSize } from 'web/hooks/use-window-size' import { useUnseenPreferredNotifications } from 'web/hooks/use-notifications' import { ChatIcon, ChevronDownIcon } from '@heroicons/react/outline' +import { setNotificationsAsSeen } from 'web/pages/notifications' export function GroupChat(props: { messages: Comment[] @@ -83,6 +84,10 @@ export function GroupChat(props: { } }, [messages, router.asPath]) + useEffect(() => { + if (inputRef) inputRef.focus() + }, [inputRef]) + function onReplyClick(comment: Comment) { setReplyToUsername(comment.userUsername) } @@ -100,9 +105,6 @@ export function GroupChat(props: { setReplyToUsername('') inputRef?.focus() } - function focusInput() { - inputRef?.focus() - } const { width, height } = useWindowSize() const [containerRef, setContainerRef] = useState(null) @@ -140,7 +142,7 @@ export function GroupChat(props: { No messages yet. Why not{isMember ? ` ` : ' join and '} @@ -184,6 +186,17 @@ export function GroupChatInBubble(props: { }) { const { messages, user, group, tips, privateUser } = props const [shouldShowChat, setShouldShowChat] = useState(false) + const router = useRouter() + + useEffect(() => { + if (router.asPath.includes('/chat')) { + setShouldShowChat(true) + } + // Leave chat open between groups if user is using chat? + // else { + // setShouldShowChat(false) + // } + }, [router.asPath]) return ( )} - {privateUser && !shouldShowChat && ( - + {privateUser && ( + )} @@ -228,36 +245,34 @@ export function GroupChatInBubble(props: { function GroupChatNotificationsIcon(props: { group: Group privateUser: PrivateUser + setAsSeen: boolean }) { - // const { privateUser, group } = props - // const router = useRouter() - // const preferredNotifications = useUnseenPreferredNotifications(privateUser, { - // customHref: '/group/', - // }) - // TODO: set notifications to seen when user clicks on chat - // // Set notification as seen if our current page is equal to the isSeenOnHref property - // useEffect(() => { - // const currentPageWithoutQuery = currentPage.split('?')[0] - // const currentPageGroupSlug = currentPageWithoutQuery.split('/')[2] - // preferredNotifications.forEach((notification) => { - // if ( - // notification.isSeenOnHref === currentPage || - // // Old chat style group chat notif was just /group/slug - // (notification.isSeenOnHref && - // currentPageWithoutQuery.includes(notification.isSeenOnHref)) || - // // They're on the home page, so if they've a chat notif, they're seeing the chat - // (notification.isSeenOnHref?.endsWith(GROUP_CHAT_SLUG) && - // currentPageWithoutQuery.endsWith(currentPageGroupSlug)) - // ) { - // setNotificationsAsSeen([notification]) - // } - // }) - // }, [currentPage, preferredNotifications]) + const { privateUser, group, setAsSeen } = props + const preferredNotificationsForThisGroup = useUnseenPreferredNotifications( + privateUser, + { + customHref: `/group/${group.slug}`, + } + ) + // Set notification as seen if our current page is equal to the isSeenOnHref property + useEffect(() => { + preferredNotificationsForThisGroup.forEach((notification) => { + if ( + (setAsSeen && notification.isSeenOnHref?.includes('chat')) || + // old style chat notif that simply ended with the group slug + notification.isSeenOnHref?.endsWith(group.slug) + ) { + setNotificationsAsSeen([notification]) + } + }) + }, [group.slug, preferredNotificationsForThisGroup, setAsSeen]) return (
0 && !setAsSeen + ? 'absolute right-4 top-4 h-3 w-3 rounded-full border-2 border-white bg-red-500' + : 'hidden' } >
) diff --git a/web/components/nav/sidebar.tsx b/web/components/nav/sidebar.tsx index 2e520179..de9fd1ba 100644 --- a/web/components/nav/sidebar.tsx +++ b/web/components/nav/sidebar.tsx @@ -18,7 +18,7 @@ import { ManifoldLogo } from './manifold-logo' import { MenuButton } from './menu' import { ProfileSummary } from './profile-menu' import NotificationsIcon from 'web/components/notifications-icon' -import React, { useState } from 'react' +import React, { useMemo, useState } from 'react' import { IS_PRIVATE_MANIFOLD } from 'common/envs/constants' import { CreateQuestionButton } from 'web/components/create-question-button' import { useMemberGroups } from 'web/hooks/use-group' @@ -215,7 +215,7 @@ export default function Sidebar(props: { className?: string }) { ) ?? [] ).map((group: Group) => ({ name: group.name, - href: `${groupPath(group.slug)}/${GROUP_CHAT_SLUG}`, + href: `${groupPath(group.slug)}`, })) return ( @@ -298,6 +298,17 @@ function GroupsList(props: { const remainingHeight = (height ?? window.innerHeight) - (containerRef?.offsetTop ?? 0) + const notifIsForThisItem = useMemo( + () => (itemHref: string) => + preferredNotifications.some( + (n) => + !n.isSeen && + (n.isSeenOnHref === itemHref || + n.isSeenOnHref?.replace('/chat', '') === itemHref) + ), + [preferredNotifications] + ) + return ( <> {memberItems.map((item) => ( - - !n.isSeen && - (n.isSeenOnHref === item.href || - n.isSeenOnHref === item.href.replace('/chat', '')) - ) && 'font-bold' - )} > - {item.name} - + + {item.name} + + ))}