Make typing for comments more fancy (#776)
This commit is contained in:
parent
f2764e9258
commit
0972de9025
|
@ -1,15 +1,11 @@
|
||||||
import type { JSONContent } from '@tiptap/core'
|
import type { JSONContent } from '@tiptap/core'
|
||||||
|
|
||||||
|
export type AnyCommentType = OnContract | OnGroup
|
||||||
|
|
||||||
// Currently, comments are created after the bet, not atomically with the bet.
|
// Currently, comments are created after the bet, not atomically with the bet.
|
||||||
// They're uniquely identified by the pair contractId/betId.
|
// They're uniquely identified by the pair contractId/betId.
|
||||||
export type Comment = {
|
export type Comment<T extends AnyCommentType = AnyCommentType> = {
|
||||||
id: string
|
id: string
|
||||||
commentType: 'contract' | 'group'
|
|
||||||
|
|
||||||
contractId?: string
|
|
||||||
groupId?: string
|
|
||||||
betId?: string
|
|
||||||
answerOutcome?: string
|
|
||||||
replyToCommentId?: string
|
replyToCommentId?: string
|
||||||
userId: string
|
userId: string
|
||||||
|
|
||||||
|
@ -22,6 +18,21 @@ export type Comment = {
|
||||||
userName: string
|
userName: string
|
||||||
userUsername: string
|
userUsername: string
|
||||||
userAvatarUrl?: string
|
userAvatarUrl?: string
|
||||||
contractSlug?: string
|
} & T
|
||||||
contractQuestion?: string
|
|
||||||
|
type OnContract = {
|
||||||
|
commentType: 'contract'
|
||||||
|
contractId: string
|
||||||
|
contractSlug: string
|
||||||
|
contractQuestion: string
|
||||||
|
answerOutcome?: string
|
||||||
|
betId?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type OnGroup = {
|
||||||
|
commentType: 'group'
|
||||||
|
groupId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ContractComment = Comment<OnContract>
|
||||||
|
export type GroupComment = Comment<OnGroup>
|
||||||
|
|
|
@ -2,7 +2,7 @@ import * as functions from 'firebase-functions'
|
||||||
import * as admin from 'firebase-admin'
|
import * as admin from 'firebase-admin'
|
||||||
import { compact, uniq } from 'lodash'
|
import { compact, uniq } from 'lodash'
|
||||||
import { getContract, getUser, getValues } from './utils'
|
import { getContract, getUser, getValues } from './utils'
|
||||||
import { Comment } from '../../common/comment'
|
import { ContractComment } from '../../common/comment'
|
||||||
import { sendNewCommentEmail } from './emails'
|
import { sendNewCommentEmail } from './emails'
|
||||||
import { Bet } from '../../common/bet'
|
import { Bet } from '../../common/bet'
|
||||||
import { Answer } from '../../common/answer'
|
import { Answer } from '../../common/answer'
|
||||||
|
@ -29,7 +29,7 @@ export const onCreateCommentOnContract = functions
|
||||||
contractQuestion: contract.question,
|
contractQuestion: contract.question,
|
||||||
})
|
})
|
||||||
|
|
||||||
const comment = change.data() as Comment
|
const comment = change.data() as ContractComment
|
||||||
const lastCommentTime = comment.createdTime
|
const lastCommentTime = comment.createdTime
|
||||||
|
|
||||||
const commentCreator = await getUser(comment.userId)
|
const commentCreator = await getUser(comment.userId)
|
||||||
|
@ -64,7 +64,7 @@ export const onCreateCommentOnContract = functions
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
const comments = await getValues<Comment>(
|
const comments = await getValues<ContractComment>(
|
||||||
firestore.collection('contracts').doc(contractId).collection('comments')
|
firestore.collection('contracts').doc(contractId).collection('comments')
|
||||||
)
|
)
|
||||||
const relatedSourceType = comment.replyToCommentId
|
const relatedSourceType = comment.replyToCommentId
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import * as functions from 'firebase-functions'
|
import * as functions from 'firebase-functions'
|
||||||
import { Comment } from '../../common/comment'
|
import { GroupComment } from '../../common/comment'
|
||||||
import * as admin from 'firebase-admin'
|
import * as admin from 'firebase-admin'
|
||||||
import { Group } from '../../common/group'
|
import { Group } from '../../common/group'
|
||||||
import { User } from '../../common/user'
|
import { User } from '../../common/user'
|
||||||
|
@ -14,7 +14,7 @@ export const onCreateCommentOnGroup = functions.firestore
|
||||||
groupId: string
|
groupId: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const comment = change.data() as Comment
|
const comment = change.data() as GroupComment
|
||||||
const creatorSnapshot = await firestore
|
const creatorSnapshot = await firestore
|
||||||
.collection('users')
|
.collection('users')
|
||||||
.doc(comment.userId)
|
.doc(comment.userId)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
|
|
||||||
import { Comment } from 'common/comment'
|
import { Comment, ContractComment } from 'common/comment'
|
||||||
import { groupConsecutive } from 'common/util/array'
|
import { groupConsecutive } from 'common/util/array'
|
||||||
import { getUsersComments } from 'web/lib/firebase/comments'
|
import { getUsersComments } from 'web/lib/firebase/comments'
|
||||||
import { SiteLink } from './site-link'
|
import { SiteLink } from './site-link'
|
||||||
|
@ -16,12 +16,6 @@ import { LoadingIndicator } from './loading-indicator'
|
||||||
|
|
||||||
const COMMENTS_PER_PAGE = 50
|
const COMMENTS_PER_PAGE = 50
|
||||||
|
|
||||||
type ContractComment = Comment & {
|
|
||||||
contractId: string
|
|
||||||
contractSlug: string
|
|
||||||
contractQuestion: string
|
|
||||||
}
|
|
||||||
|
|
||||||
function contractPath(slug: string) {
|
function contractPath(slug: string) {
|
||||||
// by convention this includes the contract creator username, but we don't
|
// by convention this includes the contract creator username, but we don't
|
||||||
// have that handy, so we just put /market/
|
// have that handy, so we just put /market/
|
||||||
|
@ -38,7 +32,9 @@ export function UserCommentsList(props: { user: User }) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getUsersComments(user.id).then((cs) => {
|
getUsersComments(user.id).then((cs) => {
|
||||||
// we don't show comments in groups here atm, just comments on contracts
|
// we don't show comments in groups here atm, just comments on contracts
|
||||||
setComments(cs.filter((c) => c.contractId) as ContractComment[])
|
setComments(
|
||||||
|
cs.filter((c) => c.commentType == 'contract') as ContractComment[]
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}, [user.id])
|
}, [user.id])
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Bet } from 'common/bet'
|
import { Bet } from 'common/bet'
|
||||||
import { Comment } from 'common/comment'
|
import { ContractComment } from 'common/comment'
|
||||||
import { resolvedPayout } from 'common/calculate'
|
import { resolvedPayout } from 'common/calculate'
|
||||||
import { Contract } from 'common/contract'
|
import { Contract } from 'common/contract'
|
||||||
import { formatMoney } from 'common/util/format'
|
import { formatMoney } from 'common/util/format'
|
||||||
|
@ -65,7 +65,7 @@ export function ContractLeaderboard(props: {
|
||||||
export function ContractTopTrades(props: {
|
export function ContractTopTrades(props: {
|
||||||
contract: Contract
|
contract: Contract
|
||||||
bets: Bet[]
|
bets: Bet[]
|
||||||
comments: Comment[]
|
comments: ContractComment[]
|
||||||
tips: CommentTipMap
|
tips: CommentTipMap
|
||||||
}) {
|
}) {
|
||||||
const { contract, bets, comments, tips } = props
|
const { contract, bets, comments, tips } = props
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Bet } from 'common/bet'
|
import { Bet } from 'common/bet'
|
||||||
import { Contract } from 'common/contract'
|
import { Contract } from 'common/contract'
|
||||||
import { Comment } from 'web/lib/firebase/comments'
|
import { ContractComment } from 'common/comment'
|
||||||
import { User } from 'common/user'
|
import { User } from 'common/user'
|
||||||
import { ContractActivity } from '../feed/contract-activity'
|
import { ContractActivity } from '../feed/contract-activity'
|
||||||
import { ContractBetsTable, BetsSummary } from '../bets-list'
|
import { ContractBetsTable, BetsSummary } from '../bets-list'
|
||||||
|
@ -15,7 +15,7 @@ export function ContractTabs(props: {
|
||||||
contract: Contract
|
contract: Contract
|
||||||
user: User | null | undefined
|
user: User | null | undefined
|
||||||
bets: Bet[]
|
bets: Bet[]
|
||||||
comments: Comment[]
|
comments: ContractComment[]
|
||||||
tips: CommentTipMap
|
tips: CommentTipMap
|
||||||
}) {
|
}) {
|
||||||
const { contract, user, bets, tips } = props
|
const { contract, user, bets, tips } = props
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { uniq, sortBy } from 'lodash'
|
||||||
import { Answer } from 'common/answer'
|
import { Answer } from 'common/answer'
|
||||||
import { Bet } from 'common/bet'
|
import { Bet } from 'common/bet'
|
||||||
import { getOutcomeProbability } from 'common/calculate'
|
import { getOutcomeProbability } from 'common/calculate'
|
||||||
import { Comment } from 'common/comment'
|
import { ContractComment } from 'common/comment'
|
||||||
import { Contract, FreeResponseContract } from 'common/contract'
|
import { Contract, FreeResponseContract } from 'common/contract'
|
||||||
import { User } from 'common/user'
|
import { User } from 'common/user'
|
||||||
import { CommentTipMap } from 'web/hooks/use-tip-txns'
|
import { CommentTipMap } from 'web/hooks/use-tip-txns'
|
||||||
|
@ -28,7 +28,7 @@ type BaseActivityItem = {
|
||||||
export type CommentInputItem = BaseActivityItem & {
|
export type CommentInputItem = BaseActivityItem & {
|
||||||
type: 'commentInput'
|
type: 'commentInput'
|
||||||
betsByCurrentUser: Bet[]
|
betsByCurrentUser: Bet[]
|
||||||
commentsByCurrentUser: Comment[]
|
commentsByCurrentUser: ContractComment[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DescriptionItem = BaseActivityItem & {
|
export type DescriptionItem = BaseActivityItem & {
|
||||||
|
@ -50,8 +50,8 @@ export type BetItem = BaseActivityItem & {
|
||||||
|
|
||||||
export type CommentThreadItem = BaseActivityItem & {
|
export type CommentThreadItem = BaseActivityItem & {
|
||||||
type: 'commentThread'
|
type: 'commentThread'
|
||||||
parentComment: Comment
|
parentComment: ContractComment
|
||||||
comments: Comment[]
|
comments: ContractComment[]
|
||||||
tips: CommentTipMap
|
tips: CommentTipMap
|
||||||
bets: Bet[]
|
bets: Bet[]
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ export type AnswerGroupItem = BaseActivityItem & {
|
||||||
type: 'answergroup'
|
type: 'answergroup'
|
||||||
user: User | undefined | null
|
user: User | undefined | null
|
||||||
answer: Answer
|
answer: Answer
|
||||||
comments: Comment[]
|
comments: ContractComment[]
|
||||||
tips: CommentTipMap
|
tips: CommentTipMap
|
||||||
bets: Bet[]
|
bets: Bet[]
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ export type LiquidityItem = BaseActivityItem & {
|
||||||
function getAnswerAndCommentInputGroups(
|
function getAnswerAndCommentInputGroups(
|
||||||
contract: FreeResponseContract,
|
contract: FreeResponseContract,
|
||||||
bets: Bet[],
|
bets: Bet[],
|
||||||
comments: Comment[],
|
comments: ContractComment[],
|
||||||
tips: CommentTipMap,
|
tips: CommentTipMap,
|
||||||
user: User | undefined | null
|
user: User | undefined | null
|
||||||
) {
|
) {
|
||||||
|
@ -116,7 +116,7 @@ function getAnswerAndCommentInputGroups(
|
||||||
|
|
||||||
function getCommentThreads(
|
function getCommentThreads(
|
||||||
bets: Bet[],
|
bets: Bet[],
|
||||||
comments: Comment[],
|
comments: ContractComment[],
|
||||||
tips: CommentTipMap,
|
tips: CommentTipMap,
|
||||||
contract: Contract
|
contract: Contract
|
||||||
) {
|
) {
|
||||||
|
@ -135,7 +135,7 @@ function getCommentThreads(
|
||||||
return items
|
return items
|
||||||
}
|
}
|
||||||
|
|
||||||
function commentIsGeneralComment(comment: Comment, contract: Contract) {
|
function commentIsGeneralComment(comment: ContractComment, contract: Contract) {
|
||||||
return (
|
return (
|
||||||
comment.answerOutcome === undefined &&
|
comment.answerOutcome === undefined &&
|
||||||
(contract.outcomeType === 'FREE_RESPONSE'
|
(contract.outcomeType === 'FREE_RESPONSE'
|
||||||
|
@ -147,7 +147,7 @@ function commentIsGeneralComment(comment: Comment, contract: Contract) {
|
||||||
export function getSpecificContractActivityItems(
|
export function getSpecificContractActivityItems(
|
||||||
contract: Contract,
|
contract: Contract,
|
||||||
bets: Bet[],
|
bets: Bet[],
|
||||||
comments: Comment[],
|
comments: ContractComment[],
|
||||||
liquidityProvisions: LiquidityProvision[],
|
liquidityProvisions: LiquidityProvision[],
|
||||||
tips: CommentTipMap,
|
tips: CommentTipMap,
|
||||||
user: User | null | undefined,
|
user: User | null | undefined,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Contract } from 'web/lib/firebase/contracts'
|
import { Contract } from 'web/lib/firebase/contracts'
|
||||||
import { Comment } from 'web/lib/firebase/comments'
|
import { ContractComment } from 'common/comment'
|
||||||
import { Bet } from 'common/bet'
|
import { Bet } from 'common/bet'
|
||||||
import { useBets } from 'web/hooks/use-bets'
|
import { useBets } from 'web/hooks/use-bets'
|
||||||
import { getSpecificContractActivityItems } from './activity-items'
|
import { getSpecificContractActivityItems } from './activity-items'
|
||||||
|
@ -12,7 +12,7 @@ import { LiquidityProvision } from 'common/liquidity-provision'
|
||||||
export function ContractActivity(props: {
|
export function ContractActivity(props: {
|
||||||
contract: Contract
|
contract: Contract
|
||||||
bets: Bet[]
|
bets: Bet[]
|
||||||
comments: Comment[]
|
comments: ContractComment[]
|
||||||
liquidityProvisions: LiquidityProvision[]
|
liquidityProvisions: LiquidityProvision[]
|
||||||
tips: CommentTipMap
|
tips: CommentTipMap
|
||||||
user: User | null | undefined
|
user: User | null | undefined
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Answer } from 'common/answer'
|
import { Answer } from 'common/answer'
|
||||||
import { Bet } from 'common/bet'
|
import { Bet } from 'common/bet'
|
||||||
import { Comment } from 'common/comment'
|
import { ContractComment } from 'common/comment'
|
||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { Col } from 'web/components/layout/col'
|
import { Col } from 'web/components/layout/col'
|
||||||
import { Row } from 'web/components/layout/row'
|
import { Row } from 'web/components/layout/row'
|
||||||
|
@ -24,7 +24,7 @@ export function FeedAnswerCommentGroup(props: {
|
||||||
contract: any
|
contract: any
|
||||||
user: User | undefined | null
|
user: User | undefined | null
|
||||||
answer: Answer
|
answer: Answer
|
||||||
comments: Comment[]
|
comments: ContractComment[]
|
||||||
tips: CommentTipMap
|
tips: CommentTipMap
|
||||||
bets: Bet[]
|
bets: Bet[]
|
||||||
}) {
|
}) {
|
||||||
|
@ -69,7 +69,7 @@ export function FeedAnswerCommentGroup(props: {
|
||||||
])
|
])
|
||||||
|
|
||||||
const scrollAndOpenReplyInput = useEvent(
|
const scrollAndOpenReplyInput = useEvent(
|
||||||
(comment?: Comment, answer?: Answer) => {
|
(comment?: ContractComment, answer?: Answer) => {
|
||||||
setReplyToUser(
|
setReplyToUser(
|
||||||
comment
|
comment
|
||||||
? { id: comment.userId, username: comment.userUsername }
|
? { id: comment.userId, username: comment.userUsername }
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Bet } from 'common/bet'
|
import { Bet } from 'common/bet'
|
||||||
import { Comment } from 'common/comment'
|
import { ContractComment } from 'common/comment'
|
||||||
import { User } from 'common/user'
|
import { User } from 'common/user'
|
||||||
import { Contract } from 'common/contract'
|
import { Contract } from 'common/contract'
|
||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
|
@ -32,9 +32,9 @@ import { Editor } from '@tiptap/react'
|
||||||
|
|
||||||
export function FeedCommentThread(props: {
|
export function FeedCommentThread(props: {
|
||||||
contract: Contract
|
contract: Contract
|
||||||
comments: Comment[]
|
comments: ContractComment[]
|
||||||
tips: CommentTipMap
|
tips: CommentTipMap
|
||||||
parentComment: Comment
|
parentComment: ContractComment
|
||||||
bets: Bet[]
|
bets: Bet[]
|
||||||
smallAvatar?: boolean
|
smallAvatar?: boolean
|
||||||
}) {
|
}) {
|
||||||
|
@ -50,7 +50,7 @@ export function FeedCommentThread(props: {
|
||||||
)
|
)
|
||||||
commentsList.unshift(parentComment)
|
commentsList.unshift(parentComment)
|
||||||
|
|
||||||
function scrollAndOpenReplyInput(comment: Comment) {
|
function scrollAndOpenReplyInput(comment: ContractComment) {
|
||||||
setReplyToUser({ id: comment.userId, username: comment.userUsername })
|
setReplyToUser({ id: comment.userId, username: comment.userUsername })
|
||||||
setShowReply(true)
|
setShowReply(true)
|
||||||
}
|
}
|
||||||
|
@ -95,10 +95,10 @@ export function FeedCommentThread(props: {
|
||||||
|
|
||||||
export function CommentRepliesList(props: {
|
export function CommentRepliesList(props: {
|
||||||
contract: Contract
|
contract: Contract
|
||||||
commentsList: Comment[]
|
commentsList: ContractComment[]
|
||||||
betsByUserId: Dictionary<Bet[]>
|
betsByUserId: Dictionary<Bet[]>
|
||||||
tips: CommentTipMap
|
tips: CommentTipMap
|
||||||
scrollAndOpenReplyInput: (comment: Comment) => void
|
scrollAndOpenReplyInput: (comment: ContractComment) => void
|
||||||
bets: Bet[]
|
bets: Bet[]
|
||||||
treatFirstIndexEqually?: boolean
|
treatFirstIndexEqually?: boolean
|
||||||
smallAvatar?: boolean
|
smallAvatar?: boolean
|
||||||
|
@ -156,12 +156,12 @@ export function CommentRepliesList(props: {
|
||||||
|
|
||||||
export function FeedComment(props: {
|
export function FeedComment(props: {
|
||||||
contract: Contract
|
contract: Contract
|
||||||
comment: Comment
|
comment: ContractComment
|
||||||
tips: CommentTips
|
tips: CommentTips
|
||||||
betsBySameUser: Bet[]
|
betsBySameUser: Bet[]
|
||||||
probAtCreatedTime?: number
|
probAtCreatedTime?: number
|
||||||
smallAvatar?: boolean
|
smallAvatar?: boolean
|
||||||
onReplyClick?: (comment: Comment) => void
|
onReplyClick?: (comment: ContractComment) => void
|
||||||
}) {
|
}) {
|
||||||
const {
|
const {
|
||||||
contract,
|
contract,
|
||||||
|
@ -274,7 +274,7 @@ export function FeedComment(props: {
|
||||||
|
|
||||||
export function getMostRecentCommentableBet(
|
export function getMostRecentCommentableBet(
|
||||||
betsByCurrentUser: Bet[],
|
betsByCurrentUser: Bet[],
|
||||||
commentsByCurrentUser: Comment[],
|
commentsByCurrentUser: ContractComment[],
|
||||||
user?: User | null,
|
user?: User | null,
|
||||||
answerOutcome?: string
|
answerOutcome?: string
|
||||||
) {
|
) {
|
||||||
|
@ -319,7 +319,7 @@ function CommentStatus(props: {
|
||||||
export function CommentInput(props: {
|
export function CommentInput(props: {
|
||||||
contract: Contract
|
contract: Contract
|
||||||
betsByCurrentUser: Bet[]
|
betsByCurrentUser: Bet[]
|
||||||
commentsByCurrentUser: Comment[]
|
commentsByCurrentUser: ContractComment[]
|
||||||
replyToUser?: { id: string; username: string }
|
replyToUser?: { id: string; username: string }
|
||||||
// Reply to a free response answer
|
// Reply to a free response answer
|
||||||
parentAnswerOutcome?: string
|
parentAnswerOutcome?: string
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { groupBy, mapValues, maxBy, sortBy } from 'lodash'
|
import { groupBy, mapValues, maxBy, sortBy } from 'lodash'
|
||||||
import { Contract } from 'web/lib/firebase/contracts'
|
import { Contract } from 'web/lib/firebase/contracts'
|
||||||
import { Comment } from 'web/lib/firebase/comments'
|
import { ContractComment } from 'common/comment'
|
||||||
import { Bet } from 'common/bet'
|
import { Bet } from 'common/bet'
|
||||||
|
|
||||||
const MAX_ACTIVE_CONTRACTS = 75
|
const MAX_ACTIVE_CONTRACTS = 75
|
||||||
|
@ -19,7 +19,7 @@ function lastActivityTime(contract: Contract) {
|
||||||
// - Bet on market
|
// - Bet on market
|
||||||
export function findActiveContracts(
|
export function findActiveContracts(
|
||||||
allContracts: Contract[],
|
allContracts: Contract[],
|
||||||
recentComments: Comment[],
|
recentComments: ContractComment[],
|
||||||
recentBets: Bet[],
|
recentBets: Bet[],
|
||||||
seenContracts: { [contractId: string]: number }
|
seenContracts: { [contractId: string]: number }
|
||||||
) {
|
) {
|
||||||
|
@ -73,7 +73,7 @@ export function findActiveContracts(
|
||||||
)
|
)
|
||||||
const contractMostRecentComment = mapValues(
|
const contractMostRecentComment = mapValues(
|
||||||
contractComments,
|
contractComments,
|
||||||
(comments) => maxBy(comments, (c) => c.createdTime) as Comment
|
(comments) => maxBy(comments, (c) => c.createdTime) as ContractComment
|
||||||
)
|
)
|
||||||
|
|
||||||
const prioritizedContracts = sortBy(activeContracts, (c) => {
|
const prioritizedContracts = sortBy(activeContracts, (c) => {
|
||||||
|
|
|
@ -4,7 +4,8 @@ import { PrivateUser, User } from 'common/user'
|
||||||
import React, { useEffect, memo, useState, useMemo } from 'react'
|
import React, { useEffect, memo, useState, useMemo } from 'react'
|
||||||
import { Avatar } from 'web/components/avatar'
|
import { Avatar } from 'web/components/avatar'
|
||||||
import { Group } from 'common/group'
|
import { Group } from 'common/group'
|
||||||
import { Comment, createCommentOnGroup } from 'web/lib/firebase/comments'
|
import { Comment, GroupComment } from 'common/comment'
|
||||||
|
import { createCommentOnGroup } from 'web/lib/firebase/comments'
|
||||||
import { CommentInputTextArea } from 'web/components/feed/feed-comments'
|
import { CommentInputTextArea } from 'web/components/feed/feed-comments'
|
||||||
import { track } from 'web/lib/service/analytics'
|
import { track } from 'web/lib/service/analytics'
|
||||||
import { firebaseLogin } from 'web/lib/firebase/users'
|
import { firebaseLogin } from 'web/lib/firebase/users'
|
||||||
|
@ -24,7 +25,7 @@ import { setNotificationsAsSeen } from 'web/pages/notifications'
|
||||||
import { usePrivateUser } from 'web/hooks/use-user'
|
import { usePrivateUser } from 'web/hooks/use-user'
|
||||||
|
|
||||||
export function GroupChat(props: {
|
export function GroupChat(props: {
|
||||||
messages: Comment[]
|
messages: GroupComment[]
|
||||||
user: User | null | undefined
|
user: User | null | undefined
|
||||||
group: Group
|
group: Group
|
||||||
tips: CommentTipMap
|
tips: CommentTipMap
|
||||||
|
@ -58,7 +59,7 @@ export function GroupChat(props: {
|
||||||
// array of groups, where each group is an array of messages that are displayed as one
|
// array of groups, where each group is an array of messages that are displayed as one
|
||||||
const groupedMessages = useMemo(() => {
|
const groupedMessages = useMemo(() => {
|
||||||
// Group messages with createdTime within 2 minutes of each other.
|
// Group messages with createdTime within 2 minutes of each other.
|
||||||
const tempGrouped: Comment[][] = []
|
const tempGrouped: GroupComment[][] = []
|
||||||
for (let i = 0; i < messages.length; i++) {
|
for (let i = 0; i < messages.length; i++) {
|
||||||
const message = messages[i]
|
const message = messages[i]
|
||||||
if (i === 0) tempGrouped.push([message])
|
if (i === 0) tempGrouped.push([message])
|
||||||
|
@ -193,7 +194,7 @@ export function GroupChat(props: {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function GroupChatInBubble(props: {
|
export function GroupChatInBubble(props: {
|
||||||
messages: Comment[]
|
messages: GroupComment[]
|
||||||
user: User | null | undefined
|
user: User | null | undefined
|
||||||
privateUser: PrivateUser | null | undefined
|
privateUser: PrivateUser | null | undefined
|
||||||
group: Group
|
group: Group
|
||||||
|
@ -309,7 +310,7 @@ function GroupChatNotificationsIcon(props: {
|
||||||
|
|
||||||
const GroupMessage = memo(function GroupMessage_(props: {
|
const GroupMessage = memo(function GroupMessage_(props: {
|
||||||
user: User | null | undefined
|
user: User | null | undefined
|
||||||
comments: Comment[]
|
comments: GroupComment[]
|
||||||
group: Group
|
group: Group
|
||||||
onReplyClick?: (comment: Comment) => void
|
onReplyClick?: (comment: Comment) => void
|
||||||
setRef?: (ref: HTMLDivElement) => void
|
setRef?: (ref: HTMLDivElement) => void
|
||||||
|
|
|
@ -42,6 +42,10 @@ export function Tipper(prop: { comment: Comment; tips: CommentTips }) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const contractId =
|
||||||
|
comment.commentType === 'contract' ? comment.contractId : undefined
|
||||||
|
const groupId =
|
||||||
|
comment.commentType === 'group' ? comment.groupId : undefined
|
||||||
await transact({
|
await transact({
|
||||||
amount: change,
|
amount: change,
|
||||||
fromId: user.id,
|
fromId: user.id,
|
||||||
|
@ -50,18 +54,14 @@ export function Tipper(prop: { comment: Comment; tips: CommentTips }) {
|
||||||
toType: 'USER',
|
toType: 'USER',
|
||||||
token: 'M$',
|
token: 'M$',
|
||||||
category: 'TIP',
|
category: 'TIP',
|
||||||
data: {
|
data: { commentId: comment.id, contractId, groupId },
|
||||||
contractId: comment.contractId,
|
|
||||||
commentId: comment.id,
|
|
||||||
groupId: comment.groupId,
|
|
||||||
},
|
|
||||||
description: `${user.name} tipped M$ ${change} to ${comment.userName} for a comment`,
|
description: `${user.name} tipped M$ ${change} to ${comment.userName} for a comment`,
|
||||||
})
|
})
|
||||||
|
|
||||||
track('send comment tip', {
|
track('send comment tip', {
|
||||||
contractId: comment.contractId,
|
|
||||||
commentId: comment.id,
|
commentId: comment.id,
|
||||||
groupId: comment.groupId,
|
contractId,
|
||||||
|
groupId,
|
||||||
amount: change,
|
amount: change,
|
||||||
fromId: user.id,
|
fromId: user.id,
|
||||||
toId: comment.userId,
|
toId: comment.userId,
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
|
import { Comment, ContractComment, GroupComment } from 'common/comment'
|
||||||
import {
|
import {
|
||||||
Comment,
|
|
||||||
listenForCommentsOnContract,
|
listenForCommentsOnContract,
|
||||||
listenForCommentsOnGroup,
|
listenForCommentsOnGroup,
|
||||||
listenForRecentComments,
|
listenForRecentComments,
|
||||||
} from 'web/lib/firebase/comments'
|
} from 'web/lib/firebase/comments'
|
||||||
|
|
||||||
export const useComments = (contractId: string) => {
|
export const useComments = (contractId: string) => {
|
||||||
const [comments, setComments] = useState<Comment[] | undefined>()
|
const [comments, setComments] = useState<ContractComment[] | undefined>()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (contractId) return listenForCommentsOnContract(contractId, setComments)
|
if (contractId) return listenForCommentsOnContract(contractId, setComments)
|
||||||
|
@ -16,7 +16,7 @@ export const useComments = (contractId: string) => {
|
||||||
return comments
|
return comments
|
||||||
}
|
}
|
||||||
export const useCommentsOnGroup = (groupId: string | undefined) => {
|
export const useCommentsOnGroup = (groupId: string | undefined) => {
|
||||||
const [comments, setComments] = useState<Comment[] | undefined>()
|
const [comments, setComments] = useState<GroupComment[] | undefined>()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (groupId) return listenForCommentsOnGroup(groupId, setComments)
|
if (groupId) return listenForCommentsOnGroup(groupId, setComments)
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {
|
||||||
import { getValues, listenForValues } from './utils'
|
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, ContractComment, GroupComment } from 'common/comment'
|
||||||
import { removeUndefinedProps } from 'common/util/object'
|
import { removeUndefinedProps } from 'common/util/object'
|
||||||
import { track } from '@amplitude/analytics-browser'
|
import { track } from '@amplitude/analytics-browser'
|
||||||
import { JSONContent } from '@tiptap/react'
|
import { JSONContent } from '@tiptap/react'
|
||||||
|
@ -31,7 +31,8 @@ export async function createCommentOnContract(
|
||||||
const ref = betId
|
const ref = betId
|
||||||
? doc(getCommentsCollection(contractId), betId)
|
? doc(getCommentsCollection(contractId), betId)
|
||||||
: doc(getCommentsCollection(contractId))
|
: doc(getCommentsCollection(contractId))
|
||||||
const comment: Comment = removeUndefinedProps({
|
// contract slug and question are set via trigger
|
||||||
|
const comment = removeUndefinedProps({
|
||||||
id: ref.id,
|
id: ref.id,
|
||||||
commentType: 'contract',
|
commentType: 'contract',
|
||||||
contractId,
|
contractId,
|
||||||
|
@ -60,7 +61,7 @@ export async function createCommentOnGroup(
|
||||||
replyToCommentId?: string
|
replyToCommentId?: string
|
||||||
) {
|
) {
|
||||||
const ref = doc(getCommentsOnGroupCollection(groupId))
|
const ref = doc(getCommentsOnGroupCollection(groupId))
|
||||||
const comment: Comment = removeUndefinedProps({
|
const comment = removeUndefinedProps({
|
||||||
id: ref.id,
|
id: ref.id,
|
||||||
commentType: 'group',
|
commentType: 'group',
|
||||||
groupId,
|
groupId,
|
||||||
|
@ -96,7 +97,7 @@ export async function listAllComments(contractId: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function listAllCommentsOnGroup(groupId: string) {
|
export async function listAllCommentsOnGroup(groupId: string) {
|
||||||
const comments = await getValues<Comment>(
|
const comments = await getValues<GroupComment>(
|
||||||
getCommentsOnGroupCollection(groupId)
|
getCommentsOnGroupCollection(groupId)
|
||||||
)
|
)
|
||||||
comments.sort((c1, c2) => c1.createdTime - c2.createdTime)
|
comments.sort((c1, c2) => c1.createdTime - c2.createdTime)
|
||||||
|
@ -105,9 +106,9 @@ export async function listAllCommentsOnGroup(groupId: string) {
|
||||||
|
|
||||||
export function listenForCommentsOnContract(
|
export function listenForCommentsOnContract(
|
||||||
contractId: string,
|
contractId: string,
|
||||||
setComments: (comments: Comment[]) => void
|
setComments: (comments: ContractComment[]) => void
|
||||||
) {
|
) {
|
||||||
return listenForValues<Comment>(
|
return listenForValues<ContractComment>(
|
||||||
getCommentsCollection(contractId),
|
getCommentsCollection(contractId),
|
||||||
(comments) => {
|
(comments) => {
|
||||||
comments.sort((c1, c2) => c1.createdTime - c2.createdTime)
|
comments.sort((c1, c2) => c1.createdTime - c2.createdTime)
|
||||||
|
@ -117,9 +118,9 @@ export function listenForCommentsOnContract(
|
||||||
}
|
}
|
||||||
export function listenForCommentsOnGroup(
|
export function listenForCommentsOnGroup(
|
||||||
groupId: string,
|
groupId: string,
|
||||||
setComments: (comments: Comment[]) => void
|
setComments: (comments: GroupComment[]) => void
|
||||||
) {
|
) {
|
||||||
return listenForValues<Comment>(
|
return listenForValues<GroupComment>(
|
||||||
getCommentsOnGroupCollection(groupId),
|
getCommentsOnGroupCollection(groupId),
|
||||||
(comments) => {
|
(comments) => {
|
||||||
comments.sort((c1, c2) => c1.createdTime - c2.createdTime)
|
comments.sort((c1, c2) => c1.createdTime - c2.createdTime)
|
||||||
|
|
|
@ -17,7 +17,7 @@ import {
|
||||||
import { SEO } from 'web/components/SEO'
|
import { SEO } from 'web/components/SEO'
|
||||||
import { Page } from 'web/components/page'
|
import { Page } from 'web/components/page'
|
||||||
import { Bet, listAllBets } from 'web/lib/firebase/bets'
|
import { Bet, listAllBets } from 'web/lib/firebase/bets'
|
||||||
import { Comment, listAllComments } from 'web/lib/firebase/comments'
|
import { listAllComments } from 'web/lib/firebase/comments'
|
||||||
import Custom404 from '../404'
|
import Custom404 from '../404'
|
||||||
import { AnswersPanel } from 'web/components/answers/answers-panel'
|
import { AnswersPanel } from 'web/components/answers/answers-panel'
|
||||||
import { fromPropz, usePropz } from 'web/hooks/use-propz'
|
import { fromPropz, usePropz } from 'web/hooks/use-propz'
|
||||||
|
@ -38,6 +38,7 @@ import { CommentTipMap, useTipTxns } from 'web/hooks/use-tip-txns'
|
||||||
import { useSaveReferral } from 'web/hooks/use-save-referral'
|
import { useSaveReferral } from 'web/hooks/use-save-referral'
|
||||||
import { getOpenGraphProps } from 'web/components/contract/contract-card-preview'
|
import { getOpenGraphProps } from 'web/components/contract/contract-card-preview'
|
||||||
import { User } from 'common/user'
|
import { User } from 'common/user'
|
||||||
|
import { ContractComment } from 'common/comment'
|
||||||
import { listUsers } from 'web/lib/firebase/users'
|
import { listUsers } from 'web/lib/firebase/users'
|
||||||
import { FeedComment } from 'web/components/feed/feed-comments'
|
import { FeedComment } from 'web/components/feed/feed-comments'
|
||||||
import { Title } from 'web/components/title'
|
import { Title } from 'web/components/title'
|
||||||
|
@ -78,7 +79,7 @@ export default function ContractPage(props: {
|
||||||
contract: Contract | null
|
contract: Contract | null
|
||||||
username: string
|
username: string
|
||||||
bets: Bet[]
|
bets: Bet[]
|
||||||
comments: Comment[]
|
comments: ContractComment[]
|
||||||
slug: string
|
slug: string
|
||||||
backToHome?: () => void
|
backToHome?: () => void
|
||||||
}) {
|
}) {
|
||||||
|
@ -314,7 +315,7 @@ function ContractLeaderboard(props: { contract: Contract; bets: Bet[] }) {
|
||||||
function ContractTopTrades(props: {
|
function ContractTopTrades(props: {
|
||||||
contract: Contract
|
contract: Contract
|
||||||
bets: Bet[]
|
bets: Bet[]
|
||||||
comments: Comment[]
|
comments: ContractComment[]
|
||||||
tips: CommentTipMap
|
tips: CommentTipMap
|
||||||
}) {
|
}) {
|
||||||
const { contract, bets, comments, tips } = props
|
const { contract, bets, comments, tips } = props
|
||||||
|
|
|
@ -46,7 +46,7 @@ import { ENV_CONFIG } from 'common/envs/constants'
|
||||||
import { useSaveReferral } from 'web/hooks/use-save-referral'
|
import { useSaveReferral } from 'web/hooks/use-save-referral'
|
||||||
import { Button } from 'web/components/button'
|
import { Button } from 'web/components/button'
|
||||||
import { listAllCommentsOnGroup } from 'web/lib/firebase/comments'
|
import { listAllCommentsOnGroup } from 'web/lib/firebase/comments'
|
||||||
import { Comment } from 'common/comment'
|
import { GroupComment } from 'common/comment'
|
||||||
import { GroupChat } from 'web/components/groups/group-chat'
|
import { GroupChat } from 'web/components/groups/group-chat'
|
||||||
|
|
||||||
export const getStaticProps = fromPropz(getStaticPropz)
|
export const getStaticProps = fromPropz(getStaticPropz)
|
||||||
|
@ -123,7 +123,7 @@ export default function GroupPage(props: {
|
||||||
topTraders: User[]
|
topTraders: User[]
|
||||||
creatorScores: { [userId: string]: number }
|
creatorScores: { [userId: string]: number }
|
||||||
topCreators: User[]
|
topCreators: User[]
|
||||||
messages: Comment[]
|
messages: GroupComment[]
|
||||||
}) {
|
}) {
|
||||||
props = usePropz(props, getStaticPropz) ?? {
|
props = usePropz(props, getStaticPropz) ?? {
|
||||||
group: null,
|
group: null,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user