diff --git a/common/util/array.ts b/common/util/array.ts index 2ad86843..8a429262 100644 --- a/common/util/array.ts +++ b/common/util/array.ts @@ -17,3 +17,22 @@ export function buildArray( return array } + +export function groupConsecutive(xs: T[], key: (x: T) => U) { + if (!xs.length) { + return [] + } + const result = [] + let curr = { key: key(xs[0]), items: [xs[0]] } + for (const x of xs.slice(1)) { + const k = key(x) + if (k !== curr.key) { + result.push(curr) + curr = { key: k, items: [x] } + } else { + curr.items.push(x) + } + } + result.push(curr) + return result +} diff --git a/web/components/comments-list.tsx b/web/components/comments-list.tsx index f816ea6b..0790b9c7 100644 --- a/web/components/comments-list.tsx +++ b/web/components/comments-list.tsx @@ -1,9 +1,9 @@ import { useEffect, useState } from 'react' -import { Dictionary, groupBy, keyBy } from 'lodash' +import { Dictionary, groupBy, keyBy, mapValues, uniq } from 'lodash' import { Comment } from 'common/comment' import { Contract } from 'common/contract' -import { filterDefined } from 'common/util/array' +import { filterDefined, groupConsecutive } from 'common/util/array' import { contractPath } from 'web/lib/firebase/contracts' import { getUsersComments } from 'web/lib/firebase/comments' import { getContractFromId } from 'web/lib/firebase/contracts' @@ -15,29 +15,34 @@ import { UserLink } from './user-page' import { User } from 'common/user' import { Col } from './layout/col' import { Content } from './editor' +import { Pagination } from './pagination' import { LoadingIndicator } from './loading-indicator' +const COMMENTS_PER_PAGE = 50 + +type ContractComment = Comment & { contractId: string } + export function UserCommentsList(props: { user: User }) { const { user } = props - const [comments, setComments] = useState | undefined>() + const [comments, setComments] = useState() const [contracts, setContracts] = useState | undefined>() + const [page, setPage] = useState(0) + const start = page * COMMENTS_PER_PAGE + const end = start + COMMENTS_PER_PAGE useEffect(() => { getUsersComments(user.id).then((cs) => { // we don't show comments in groups here atm, just comments on contracts - const contractComments = cs.filter((c) => c.contractId) - const commentsByContractId = groupBy(contractComments, 'contractId') - setComments(commentsByContractId) + setComments(cs.filter((c) => c.contractId) as ContractComment[]) }) }, [user.id]) useEffect(() => { if (comments) { - Promise.all(Object.keys(comments).map(getContractFromId)).then( - (contracts) => { - setContracts(keyBy(filterDefined(contracts), 'id')) - } - ) + const contractIds = uniq(comments.map((c) => c.contractId)) + Promise.all(contractIds.map(getContractFromId)).then((contracts) => { + setContracts(keyBy(filterDefined(contracts), 'id')) + }) } }, [comments]) @@ -45,12 +50,16 @@ export function UserCommentsList(props: { user: User }) { return } + const pageComments = groupConsecutive( + comments.slice(start, end), + (c) => c.contractId + ) return ( - {Object.entries(comments).map(([contractId, comments]) => { - const contract = contracts[contractId] + {pageComments.map(({ key, items }, i) => { + const contract = contracts[key] return ( -
+
- {comments.map((comment) => ( + {items.map((comment) => ( ) })} + ) }