Refactor to share logic

This commit is contained in:
Ian Philips 2022-04-21 09:15:40 -06:00
parent 5861817e5a
commit 6de12efa99
3 changed files with 49 additions and 54 deletions

View File

@ -12,7 +12,6 @@ import {
} from '../../../common/contract' } from '../../../common/contract'
import { User } from '../../../common/user' import { User } from '../../../common/user'
import { mapCommentsByBetId } from '../../lib/firebase/comments' import { mapCommentsByBetId } from '../../lib/firebase/comments'
import { useUser } from '../../hooks/use-user'
export type ActivityItem = export type ActivityItem =
| DescriptionItem | DescriptionItem
@ -33,7 +32,7 @@ type BaseActivityItem = {
export type CommentInputItem = BaseActivityItem & { export type CommentInputItem = BaseActivityItem & {
type: 'commentInput' type: 'commentInput'
bets: Bet[] bets: Bet[]
comments: Comment[] commentsByBetId: Record<string, Comment>
} }
export type DescriptionItem = BaseActivityItem & { export type DescriptionItem = BaseActivityItem & {
@ -287,8 +286,7 @@ export function getAllContractActivityItems(
] ]
: [{ type: 'description', id: '0', contract }] : [{ type: 'description', id: '0', contract }]
// for each comment. turn it into an activity item and add it to the items: const commentsWithoutBets = comments
const commentWithoutBetActivityItems = comments
.filter((comment) => !comment.betId) .filter((comment) => !comment.betId)
.map((comment) => ({ .map((comment) => ({
type: 'comment' as const, type: 'comment' as const,
@ -300,15 +298,17 @@ export function getAllContractActivityItems(
hideOutcome: true, hideOutcome: true,
smallAvatar: false, smallAvatar: false,
})) }))
const groupedBets = groupBets(bets, comments, contract, user?.id, { const groupedBets = groupBets(bets, comments, contract, user?.id, {
hideOutcome: false, hideOutcome: false,
abbreviated, abbreviated,
smallAvatar: false, smallAvatar: false,
reversed: false, reversed: false,
}) })
// iterate through the bets and comment acitivity items and add them to the items in order of comment creation time:
const allActivityItems = [...commentWithoutBetActivityItems, ...groupedBets] // iterate through the bets and comment activity items and add them to the items in order of comment creation time:
const sortedActivityItems = _.sortBy(allActivityItems, (item) => { const unorderedBetsAndComments = [...commentsWithoutBets, ...groupedBets]
const sortedBetsAndComments = _.sortBy(unorderedBetsAndComments, (item) => {
if (item.type === 'comment') { if (item.type === 'comment') {
return item.comment.createdTime return item.comment.createdTime
} else if (item.type === 'bet') { } else if (item.type === 'bet') {
@ -317,7 +317,8 @@ export function getAllContractActivityItems(
return item.bets[0].createdTime return item.bets[0].createdTime
} }
}) })
items.push(...sortedActivityItems)
items.push(...sortedBetsAndComments)
if (outcomeType === 'FREE_RESPONSE') { if (outcomeType === 'FREE_RESPONSE') {
items.push( items.push(
@ -341,11 +342,13 @@ export function getAllContractActivityItems(
if (contract.resolution) { if (contract.resolution) {
items.push({ type: 'resolve', id: `${contract.resolutionTime}`, contract }) items.push({ type: 'resolve', id: `${contract.resolutionTime}`, contract })
} }
const commentsByBetId = mapCommentsByBetId(comments)
items.push({ items.push({
type: 'commentInput', type: 'commentInput',
id: 'commentInput', id: 'commentInput',
bets, bets,
comments, commentsByBetId,
contract, contract,
}) })

View File

@ -182,30 +182,33 @@ function RelativeTimestamp(props: { time: number }) {
export function CommentInput(props: { export function CommentInput(props: {
contract: Contract contract: Contract
comments: Comment[] commentsByBetId: Record<string, Comment>
bets: Bet[] bets: Bet[]
}) { }) {
// see if we can comment input on any bet: // see if we can comment input on any bet:
const { contract, bets, comments } = props const { contract, bets, commentsByBetId } = props
const user = useUser() const user = useUser()
let canCommentOnBet = false const [comment, setComment] = useState('')
if (!user) {
return <div />
}
let canCommentOnABet = false
bets.forEach((bet) => { bets.forEach((bet) => {
// make sure there is not already a comment with a mathcing bet id: // make sure there is not already a comment with a matching bet id:
const matchingComment = comments.find((comment) => comment.betId === bet.id) const matchingComment = commentsByBetId[bet.id]
if (matchingComment) { if (matchingComment) {
return return
} }
const { createdTime, userId } = bet const { createdTime, userId } = bet
const isSelf = user?.id === userId const canComment = CanComment(userId, createdTime, user)
// You can comment if your bet was posted in the last hour
const canComment = isSelf && Date.now() - createdTime < 60 * 60 * 1000
if (canComment) { if (canComment) {
// if you can comment on this bet, then you can comment on the contract canCommentOnABet = true
canCommentOnBet = true
} }
}) })
const [comment, setComment] = useState('') if (canCommentOnABet) return <div />
async function submitComment() { async function submitComment() {
if (!user || !comment) return if (!user || !comment) return
@ -213,8 +216,6 @@ export function CommentInput(props: {
setComment('') setComment('')
} }
if (canCommentOnBet) return <div />
return ( return (
<> <>
<div> <div>
@ -222,8 +223,6 @@ export function CommentInput(props: {
</div> </div>
<div className={'min-w-0 flex-1 py-1.5'}> <div className={'min-w-0 flex-1 py-1.5'}>
<div className="text-sm text-gray-500"> <div className="text-sm text-gray-500">
{/*<span>{isSelf ? 'You' : bettor ? bettor.name : 'A trader'}</span>{' '}*/}
<div className="mt-2"> <div className="mt-2">
<Textarea <Textarea
value={comment} value={comment}
@ -262,9 +261,7 @@ export function FeedBet(props: {
const { id, amount, outcome, createdTime, userId } = bet const { id, amount, outcome, createdTime, userId } = bet
const user = useUser() const user = useUser()
const isSelf = user?.id === userId const isSelf = user?.id === userId
const canComment = CanComment(userId, createdTime, user)
// You can comment if your bet was posted in the last hour
const canComment = isSelf && Date.now() - createdTime < 60 * 60 * 1000
const [comment, setComment] = useState('') const [comment, setComment] = useState('')
async function submitComment() { async function submitComment() {
@ -449,6 +446,12 @@ export function FeedQuestion(props: {
) )
} }
function CanComment(userId: string, createdTime: number, user?: User | null) {
const isSelf = user?.id === userId
// You can comment if your bet was posted in the last hour
return isSelf && Date.now() - createdTime < 60 * 60 * 1000
}
function FeedDescription(props: { contract: Contract }) { function FeedDescription(props: { contract: Contract }) {
const { contract } = props const { contract } = props
const { creatorName, creatorUsername } = contract const { creatorName, creatorUsername } = contract

View File

@ -23,11 +23,11 @@ export async function createComment(
commenter: User, commenter: User,
betId?: string betId?: string
) { ) {
if (betId) { const ref = betId
const ref = doc(getCommentsCollection(contractId), betId) ? doc(getCommentsCollection(contractId), betId)
const comment: Comment = { : doc(getCommentsCollection(contractId))
let comment: Comment = {
id: ref.id, id: ref.id,
betId: betId,
contractId, contractId,
userId: commenter.id, userId: commenter.id,
text: text.slice(0, MAX_COMMENT_LENGTH), text: text.slice(0, MAX_COMMENT_LENGTH),
@ -36,21 +36,10 @@ export async function createComment(
userUsername: commenter.username, userUsername: commenter.username,
userAvatarUrl: commenter.avatarUrl, userAvatarUrl: commenter.avatarUrl,
} }
if (betId) {
comment.betId = betId
}
return await setDoc(ref, comment) return await setDoc(ref, comment)
} else {
const newCommentRef = doc(getCommentsCollection(contractId))
let comment: Comment = {
id: newCommentRef.id,
contractId,
userId: commenter.id,
text: text.slice(0, MAX_COMMENT_LENGTH),
createdTime: Date.now(),
userName: commenter.name,
userUsername: commenter.username,
userAvatarUrl: commenter.avatarUrl,
}
return await setDoc(newCommentRef, comment)
}
} }
function getCommentsCollection(contractId: string) { function getCommentsCollection(contractId: string) {