diff --git a/web/components/groups/discussion.tsx b/web/components/groups/group-chat.tsx similarity index 81% rename from web/components/groups/discussion.tsx rename to web/components/groups/group-chat.tsx index a4a83745..5dedbc8f 100644 --- a/web/components/groups/discussion.tsx +++ b/web/components/groups/group-chat.tsx @@ -1,7 +1,7 @@ import { Row } from 'web/components/layout/row' import { Col } from 'web/components/layout/col' import { User } from 'common/user' -import React, { useEffect, memo, useState } from 'react' +import React, { useEffect, memo, useState, useMemo } from 'react' import { Avatar } from 'web/components/avatar' import { Group } from 'common/group' import { Comment, createCommentOnGroup } from 'web/lib/firebase/comments' @@ -19,7 +19,7 @@ import { UserLink } from 'web/components/user-page' import { groupPath } from 'web/lib/firebase/groups' import { CopyLinkDateTimeComponent } from 'web/components/feed/copy-link-date-time' -export function Discussion(props: { +export function GroupChat(props: { messages: Comment[] user: User | null | undefined group: Group @@ -34,8 +34,30 @@ export function Discussion(props: { useState(null) const [replyToUsername, setReplyToUsername] = useState('') const [inputRef, setInputRef] = useState(null) + const [groupedMessages, setGroupedMessages] = useState([]) const router = useRouter() + useMemo(() => { + // Group messages with createdTime within 2 minutes of each other. + const tempMessages = [] + for (let i = 0; i < messages.length; i++) { + const message = messages[i] + if (i === 0) tempMessages.push({ ...message }) + else { + const prevMessage = messages[i - 1] + const diff = message.createdTime - prevMessage.createdTime + const creatorsMatch = message.userId === prevMessage.userId + if (diff < 2 * 60 * 1000 && creatorsMatch) { + tempMessages[tempMessages.length - 1].text += `\n${message.text}` + } else { + tempMessages.push({ ...message }) + } + } + } + + setGroupedMessages(tempMessages) + }, [messages]) + useEffect(() => { scrollToMessageRef?.scrollIntoView() }, [scrollToMessageRef]) @@ -78,7 +100,7 @@ export function Discussion(props: { } ref={setScrollToBottomRef} > - {messages.map((message) => ( + {groupedMessages.map((message) => ( @@ -151,8 +173,8 @@ const GroupMessage = memo(function GroupMessage_(props: { {!isCreatorsComment && ( @@ -161,7 +183,7 @@ const GroupMessage = memo(function GroupMessage_(props: { {!isCreatorsComment ? ( ) : ( - {'You'} + {'You'} )} { return comments } +export const useCommentsOnGroup = (groupId: string | undefined) => { + const [comments, setComments] = useState() + + useEffect(() => { + if (groupId) return listenForCommentsOnGroup(groupId, setComments) + }, [groupId]) + + return comments +} export const useRecentComments = () => { const [recentComments, setRecentComments] = useState() diff --git a/web/lib/firebase/groups.ts b/web/lib/firebase/groups.ts index 09181046..40471eb4 100644 --- a/web/lib/firebase/groups.ts +++ b/web/lib/firebase/groups.ts @@ -17,7 +17,7 @@ const groupCollection = collection(db, 'groups') export function groupPath( groupSlug: string, - subpath?: 'edit' | 'questions' | 'details' | 'discussion' + subpath?: 'edit' | 'questions' | 'details' | 'chat' ) { return `/group/${groupSlug}${subpath ? `/${subpath}` : ''}` } diff --git a/web/pages/group/[...slugs]/index.tsx b/web/pages/group/[...slugs]/index.tsx index 4899f57e..b38de6d5 100644 --- a/web/pages/group/[...slugs]/index.tsx +++ b/web/pages/group/[...slugs]/index.tsx @@ -1,7 +1,6 @@ import { take, sortBy, debounce } from 'lodash' import { Group } from 'common/group' -import { Comment } from 'common/comment' import { Page } from 'web/components/page' import { Title } from 'web/components/title' import { listAllBets } from 'web/lib/firebase/bets' @@ -32,14 +31,14 @@ import { Tabs } from 'web/components/layout/tabs' import { ContractsGrid } from 'web/components/contract/contracts-list' import { CreateQuestionButton } from 'web/components/create-question-button' import React, { useEffect, useState } from 'react' -import { Discussion } from 'web/components/groups/discussion' -import { listenForCommentsOnGroup } from 'web/lib/firebase/comments' +import { GroupChat } from 'web/components/groups/group-chat' import { LoadingIndicator } from 'web/components/loading-indicator' import { Modal } from 'web/components/layout/modal' import { PlusIcon } from '@heroicons/react/outline' import { checkAgainstQuery } from 'web/hooks/use-sort-and-query-params' import { ChoicesToggleGroup } from 'web/components/choices-toggle-group' import { toast } from 'react-hot-toast' +import { useCommentsOnGroup } from 'web/hooks/use-comments' export const getStaticProps = fromPropz(getStaticPropz) export async function getStaticPropz(props: { params: { slugs: string[] } }) { @@ -92,7 +91,7 @@ async function toTopUsers(userScores: { [userId: string]: number }) { export async function getStaticPaths() { return { paths: [], fallback: 'blocking' } } -const groupSubpages = [undefined, 'discussion', 'questions', 'details'] as const +const groupSubpages = [undefined, 'chat', 'questions', 'details'] as const export default function GroupPage(props: { group: Group | null @@ -115,14 +114,11 @@ export default function GroupPage(props: { const router = useRouter() const { slugs } = router.query as { slugs: string[] } - const page = (slugs?.[1] ?? 'discussion') as typeof groupSubpages[number] + const page = (slugs?.[1] ?? 'chat') as typeof groupSubpages[number] const group = useGroup(props.group?.id) ?? props.group - const [messages, setMessages] = useState(undefined) const [contracts, setContracts] = useState(undefined) - useEffect(() => { - if (group) listenForCommentsOnGroup(group.id, setMessages) - }, [group]) + const messages = useCommentsOnGroup(group?.id) useEffect(() => { if (group) @@ -189,7 +185,9 @@ export default function GroupPage(props: {
- <span className={'text-gray-700'}>{group.about}</span> + <span className={'hidden text-gray-700 sm:block'}> + {group.about} + </span> </div> {isMember && ( <CreateQuestionButton @@ -209,13 +207,13 @@ export default function GroupPage(props: { defaultIndex={page === 'details' ? 2 : page === 'questions' ? 1 : 0} tabs={[ { - title: 'Discussion', + title: 'Chat', content: messages ? ( - <Discussion messages={messages} user={user} group={group} /> + <GroupChat messages={messages} user={user} group={group} /> ) : ( <LoadingIndicator /> ), - href: groupPath(group.slug, 'discussion'), + href: groupPath(group.slug, 'chat'), }, { title: 'Questions',