Small code improvements

This commit is contained in:
Ian Philips 2022-05-05 18:27:44 -04:00
parent e0e75d7c08
commit afbaba2020
4 changed files with 57 additions and 60 deletions

View File

@ -7,37 +7,33 @@ import { Avatar } from './avatar'
import { RelativeTimestamp } from './relative-timestamp' import { RelativeTimestamp } from './relative-timestamp'
import { UserLink } from './user-page' import { UserLink } from './user-page'
import { User } from '../../common/user' import { User } from '../../common/user'
import _, { Dictionary } from 'lodash'
import { Col } from './layout/col' import { Col } from './layout/col'
import { Linkify } from './linkify'
export function UserCommentsList(props: { export function UserCommentsList(props: {
user: User user: User
commentsByContractId: Dictionary<Comment[]> commentsByUniqueContracts: Map<Contract, Comment[]>
uniqueContracts: (Contract | undefined)[]
}) { }) {
const { commentsByContractId, uniqueContracts } = props const { commentsByUniqueContracts } = props
return ( return (
<Col className={'bg-white'}> <Col className={'bg-white'}>
{uniqueContracts.map( {Array.from(commentsByUniqueContracts).map(([contract, comments]) => (
(contract) => <div key={contract.id} className={'border-width-1 border-b p-5'}>
contract && ( <div className={'mb-2 text-sm text-indigo-700'}>
<div key={contract.id} className={'border-width-1 border-b p-5'}> <SiteLink href={contractPath(contract)}>
<div className={'mb-2 text-sm text-indigo-700'}> {contract.question}
<SiteLink href={contractPath(contract)}> </SiteLink>
{contract.question} </div>
</SiteLink> {comments.map((comment) => (
<div key={comment.id} className={'relative pb-6'}>
<div className="relative flex items-start space-x-3">
<ProfileComment comment={comment} />
</div> </div>
{commentsByContractId[contract.id].map((comment) => (
<div key={comment.id} className={'relative pb-6'}>
<div className="relative flex items-start space-x-3">
<ProfileComment comment={comment} />
</div>
</div>
))}
</div> </div>
) ))}
)} </div>
))}
</Col> </Col>
) )
} }
@ -61,7 +57,7 @@ function ProfileComment(props: { comment: Comment }) {
<RelativeTimestamp time={createdTime} /> <RelativeTimestamp time={createdTime} />
</p> </p>
</div> </div>
{text} <Linkify text={text} />
</div> </div>
</Row> </Row>
</div> </div>

View File

@ -41,38 +41,43 @@ export function UserLink(props: {
export function UserPage(props: { export function UserPage(props: {
user: User user: User
currentUser?: User currentUser?: User
defaultTabIndex?: number defaultTabTitle?: string
}) { }) {
const router = useRouter() const router = useRouter()
const { user, currentUser, defaultTabIndex } = props const { user, currentUser, defaultTabTitle } = props
const isCurrentUser = user.id === currentUser?.id const isCurrentUser = user.id === currentUser?.id
const bannerUrl = user.bannerUrl ?? defaultBannerUrl(user.id) const bannerUrl = user.bannerUrl ?? defaultBannerUrl(user.id)
const [usersComments, setUsersComments] = useState<Comment[]>([] as Comment[]) const [usersComments, setUsersComments] = useState<Comment[]>([] as Comment[])
const [usersContracts, setUsersContracts] = useState<Contract[] | 'loading'>( const [usersContracts, setUsersContracts] = useState<Contract[] | 'loading'>(
'loading' 'loading'
) )
const [uniqueContracts, setUniqueContracts] = useState< const [commentsByContract, setCommentsByContract] = useState<
(Contract | undefined)[] | 'loading' Map<Contract, Comment[]> | 'loading'
>('loading') >('loading')
useEffect(() => { useEffect(() => {
if (user) { if (!user) return
getUsersComments(user.id).then(setUsersComments) getUsersComments(user.id).then(setUsersComments)
listContracts(user.id).then(setUsersContracts) listContracts(user.id).then(setUsersContracts)
}
}, [user]) }, [user])
useEffect(() => { useEffect(() => {
// get all unique contracts for the comments and group each comments array to a contract const uniqueContractIds = _.uniq(
if (usersComments) { usersComments.map((comment) => comment.contractId)
const uniqueContractIds = _.uniq( )
usersComments.map((comment) => comment.contractId) Promise.all(
) uniqueContractIds.map((contractId) => getContractFromId(contractId))
const uniqueContracts = Array.from(uniqueContractIds).map((id) => ).then((contracts) => {
getContractFromId(id) const commentsByContract = new Map<Contract, Comment[]>()
) contracts.forEach((contract) => {
Promise.all(uniqueContracts).then(setUniqueContracts) if (!contract) return
} commentsByContract.set(
contract,
usersComments.filter((comment) => comment.contractId === contract.id)
)
})
setCommentsByContract(commentsByContract)
})
}, [usersComments]) }, [usersComments])
return ( return (
@ -179,10 +184,10 @@ export function UserPage(props: {
</Col> </Col>
<Spacer h={10} /> <Spacer h={10} />
{usersContracts !== 'loading' && uniqueContracts != 'loading' ? ( {usersContracts !== 'loading' && commentsByContract != 'loading' ? (
<Tabs <Tabs
className={'pb-2 pt-1 '} className={'pb-2 pt-1 '}
defaultIndex={defaultTabIndex} defaultIndex={defaultTabTitle === 'Comments' ? 1 : 0}
onClick={(tabName) => onClick={(tabName) =>
router.push( router.push(
{ {
@ -213,11 +218,7 @@ export function UserPage(props: {
content: ( content: (
<UserCommentsList <UserCommentsList
user={user} user={user}
commentsByContractId={_.groupBy( commentsByUniqueContracts={commentsByContract}
usersComments,
(comment) => comment.contractId
)}
uniqueContracts={uniqueContracts}
/> />
), ),
tabIcon: ( tabIcon: (

View File

@ -1,11 +1,11 @@
import { import {
doc,
collection, collection,
setDoc,
query,
collectionGroup, collectionGroup,
where, doc,
orderBy, orderBy,
query,
setDoc,
where,
} from 'firebase/firestore' } from 'firebase/firestore'
import _ from 'lodash' import _ from 'lodash'
@ -13,6 +13,7 @@ import { getValues, listenForValues } from './utils'
import { db } from './init' import { db } from './init'
import { User } from '../../../common/user' import { User } from '../../../common/user'
import { Comment } from '../../../common/comment' import { Comment } from '../../../common/comment'
export type { Comment } export type { Comment }
export const MAX_COMMENT_LENGTH = 10000 export const MAX_COMMENT_LENGTH = 10000
@ -126,13 +127,12 @@ export async function getDailyComments(
return commentsByDay return commentsByDay
} }
const getUsersCommentsQuery = (userId: string) =>
query(
collectionGroup(db, 'comments'),
where('userId', '==', userId),
orderBy('createdTime', 'desc')
)
export async function getUsersComments(userId: string) { export async function getUsersComments(userId: string) {
const getUsersCommentsQuery = (userId: string) => return await getValues<Comment>(getUsersCommentsQuery(userId))
query(
collectionGroup(db, 'comments'),
where('userId', '==', userId),
orderBy('createdTime', 'desc')
)
const comments = await getValues<Comment>(getUsersCommentsQuery(userId))
return comments
} }

View File

@ -24,7 +24,7 @@ export default function UserProfile() {
<UserPage <UserPage
user={user} user={user}
currentUser={currentUser || undefined} currentUser={currentUser || undefined}
defaultTabIndex={tab === 'Comments' || tab === 'comments' ? 1 : 0} defaultTabTitle={tab}
/> />
) : ( ) : (
<Custom404 /> <Custom404 />