2022-06-14 13:13:24 +00:00
|
|
|
import { uniq, sortBy } from 'lodash'
|
2022-03-14 20:29:32 +00:00
|
|
|
|
2022-05-09 13:04:36 +00:00
|
|
|
import { Answer } from 'common/answer'
|
|
|
|
import { Bet } from 'common/bet'
|
|
|
|
import { getOutcomeProbability } from 'common/calculate'
|
|
|
|
import { Comment } from 'common/comment'
|
2022-06-01 02:42:35 +00:00
|
|
|
import { Contract, FreeResponseContract } from 'common/contract'
|
2022-05-09 13:04:36 +00:00
|
|
|
import { User } from 'common/user'
|
2022-06-18 03:28:16 +00:00
|
|
|
import { CommentTipMap } from 'web/hooks/use-tip-txns'
|
2022-03-14 20:29:32 +00:00
|
|
|
|
|
|
|
export type ActivityItem =
|
|
|
|
| DescriptionItem
|
|
|
|
| QuestionItem
|
|
|
|
| BetItem
|
|
|
|
| AnswerGroupItem
|
|
|
|
| CloseItem
|
|
|
|
| ResolveItem
|
2022-04-21 17:09:06 +00:00
|
|
|
| CommentInputItem
|
2022-05-11 21:11:46 +00:00
|
|
|
| CommentThreadItem
|
2022-03-14 20:29:32 +00:00
|
|
|
|
|
|
|
type BaseActivityItem = {
|
|
|
|
id: string
|
|
|
|
contract: Contract
|
|
|
|
}
|
|
|
|
|
2022-04-21 17:09:06 +00:00
|
|
|
export type CommentInputItem = BaseActivityItem & {
|
|
|
|
type: 'commentInput'
|
2022-04-29 21:11:04 +00:00
|
|
|
betsByCurrentUser: Bet[]
|
2022-05-18 14:42:13 +00:00
|
|
|
commentsByCurrentUser: Comment[]
|
2022-04-21 17:09:06 +00:00
|
|
|
}
|
|
|
|
|
2022-03-14 20:29:32 +00:00
|
|
|
export type DescriptionItem = BaseActivityItem & {
|
|
|
|
type: 'description'
|
|
|
|
}
|
|
|
|
|
|
|
|
export type QuestionItem = BaseActivityItem & {
|
|
|
|
type: 'question'
|
|
|
|
showDescription: boolean
|
2022-04-11 21:13:26 +00:00
|
|
|
contractPath?: string
|
2022-03-14 20:29:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export type BetItem = BaseActivityItem & {
|
|
|
|
type: 'bet'
|
|
|
|
bet: Bet
|
|
|
|
hideOutcome: boolean
|
2022-03-14 21:56:53 +00:00
|
|
|
smallAvatar: boolean
|
2022-04-29 21:11:04 +00:00
|
|
|
hideComment?: boolean
|
2022-03-14 20:29:32 +00:00
|
|
|
}
|
|
|
|
|
2022-05-11 21:11:46 +00:00
|
|
|
export type CommentThreadItem = BaseActivityItem & {
|
|
|
|
type: 'commentThread'
|
|
|
|
parentComment: Comment
|
|
|
|
comments: Comment[]
|
2022-06-18 03:28:16 +00:00
|
|
|
tips: CommentTipMap
|
2022-05-19 01:38:02 +00:00
|
|
|
bets: Bet[]
|
2022-03-14 20:29:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export type AnswerGroupItem = BaseActivityItem & {
|
2022-05-17 15:55:26 +00:00
|
|
|
type: 'answergroup'
|
2022-06-08 13:24:12 +00:00
|
|
|
user: User | undefined | null
|
2022-03-14 20:29:32 +00:00
|
|
|
answer: Answer
|
2022-06-08 13:24:12 +00:00
|
|
|
comments: Comment[]
|
2022-06-18 03:28:16 +00:00
|
|
|
tips: CommentTipMap
|
2022-06-08 13:24:12 +00:00
|
|
|
bets: Bet[]
|
2022-03-14 20:29:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export type CloseItem = BaseActivityItem & {
|
|
|
|
type: 'close'
|
|
|
|
}
|
|
|
|
|
|
|
|
export type ResolveItem = BaseActivityItem & {
|
|
|
|
type: 'resolve'
|
|
|
|
}
|
|
|
|
|
2022-05-03 20:38:40 +00:00
|
|
|
function getAnswerAndCommentInputGroups(
|
2022-06-01 02:42:35 +00:00
|
|
|
contract: FreeResponseContract,
|
2022-05-03 20:38:40 +00:00
|
|
|
bets: Bet[],
|
|
|
|
comments: Comment[],
|
2022-06-18 03:28:16 +00:00
|
|
|
tips: CommentTipMap,
|
2022-05-03 20:38:40 +00:00
|
|
|
user: User | undefined | null
|
|
|
|
) {
|
2022-06-06 00:20:06 +00:00
|
|
|
let outcomes = uniq(bets.map((bet) => bet.outcome))
|
2022-05-22 08:36:05 +00:00
|
|
|
outcomes = sortBy(outcomes, (outcome) =>
|
2022-05-03 20:38:40 +00:00
|
|
|
getOutcomeProbability(contract, outcome)
|
|
|
|
)
|
|
|
|
|
|
|
|
const answerGroups = outcomes
|
|
|
|
.map((outcome) => {
|
|
|
|
const answer = contract.answers?.find(
|
|
|
|
(answer) => answer.id === outcome
|
|
|
|
) as Answer
|
|
|
|
|
|
|
|
return {
|
|
|
|
id: outcome,
|
|
|
|
type: 'answergroup' as const,
|
|
|
|
contract,
|
|
|
|
user,
|
2022-06-08 13:24:12 +00:00
|
|
|
answer,
|
|
|
|
comments,
|
2022-06-18 03:28:16 +00:00
|
|
|
tips,
|
2022-06-08 13:24:12 +00:00
|
|
|
bets,
|
2022-05-03 20:38:40 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
.filter((group) => group.answer) as ActivityItem[]
|
|
|
|
return answerGroups
|
|
|
|
}
|
|
|
|
|
2022-05-11 21:11:46 +00:00
|
|
|
function getCommentThreads(
|
2022-04-29 21:11:04 +00:00
|
|
|
bets: Bet[],
|
|
|
|
comments: Comment[],
|
2022-06-18 03:28:16 +00:00
|
|
|
tips: CommentTipMap,
|
2022-04-29 21:11:04 +00:00
|
|
|
contract: Contract
|
|
|
|
) {
|
2022-05-11 21:11:46 +00:00
|
|
|
const parentComments = comments.filter((comment) => !comment.replyToCommentId)
|
2022-04-29 21:11:04 +00:00
|
|
|
|
2022-05-11 21:11:46 +00:00
|
|
|
const items = parentComments.map((comment) => ({
|
|
|
|
type: 'commentThread' as const,
|
2022-04-29 21:11:04 +00:00
|
|
|
id: comment.id,
|
|
|
|
contract: contract,
|
2022-05-11 21:11:46 +00:00
|
|
|
comments: comments,
|
|
|
|
parentComment: comment,
|
2022-05-19 01:38:02 +00:00
|
|
|
bets: bets,
|
2022-06-18 03:28:16 +00:00
|
|
|
tips,
|
2022-04-29 21:11:04 +00:00
|
|
|
}))
|
|
|
|
|
|
|
|
return items
|
|
|
|
}
|
|
|
|
|
2022-05-18 14:42:13 +00:00
|
|
|
function commentIsGeneralComment(comment: Comment, contract: Contract) {
|
|
|
|
return (
|
|
|
|
comment.answerOutcome === undefined &&
|
|
|
|
(contract.outcomeType === 'FREE_RESPONSE'
|
|
|
|
? comment.betId === undefined
|
|
|
|
: true)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-04-26 21:08:50 +00:00
|
|
|
export function getSpecificContractActivityItems(
|
|
|
|
contract: Contract,
|
|
|
|
bets: Bet[],
|
|
|
|
comments: Comment[],
|
2022-06-18 03:28:16 +00:00
|
|
|
tips: CommentTipMap,
|
2022-04-26 21:08:50 +00:00
|
|
|
user: User | null | undefined,
|
|
|
|
options: {
|
2022-05-03 20:38:40 +00:00
|
|
|
mode: 'comments' | 'bets' | 'free-response-comment-answer-groups'
|
2022-04-26 21:08:50 +00:00
|
|
|
}
|
|
|
|
) {
|
|
|
|
const { mode } = options
|
2022-05-26 21:41:24 +00:00
|
|
|
const items = [] as ActivityItem[]
|
2022-04-26 21:08:50 +00:00
|
|
|
|
|
|
|
switch (mode) {
|
|
|
|
case 'bets':
|
2022-05-12 15:48:19 +00:00
|
|
|
// Remove first bet (which is the ante):
|
|
|
|
if (contract.outcomeType === 'FREE_RESPONSE') bets = bets.slice(1)
|
2022-04-26 21:08:50 +00:00
|
|
|
items.push(
|
2022-04-29 21:11:04 +00:00
|
|
|
...bets.map((bet) => ({
|
|
|
|
type: 'bet' as const,
|
2022-06-20 13:58:18 +00:00
|
|
|
id: bet.id + '-' + bet.isSold,
|
2022-04-29 21:11:04 +00:00
|
|
|
bet,
|
|
|
|
contract,
|
2022-04-26 21:08:50 +00:00
|
|
|
hideOutcome: false,
|
|
|
|
smallAvatar: false,
|
2022-04-29 21:11:04 +00:00
|
|
|
hideComment: true,
|
|
|
|
}))
|
2022-04-26 21:08:50 +00:00
|
|
|
)
|
|
|
|
break
|
2022-03-14 20:29:32 +00:00
|
|
|
|
2022-05-26 21:41:24 +00:00
|
|
|
case 'comments': {
|
2022-05-18 14:42:13 +00:00
|
|
|
const nonFreeResponseComments = comments.filter((comment) =>
|
|
|
|
commentIsGeneralComment(comment, contract)
|
2022-05-03 20:38:40 +00:00
|
|
|
)
|
|
|
|
const nonFreeResponseBets =
|
|
|
|
contract.outcomeType === 'FREE_RESPONSE' ? [] : bets
|
|
|
|
items.push(
|
2022-05-11 21:11:46 +00:00
|
|
|
...getCommentThreads(
|
2022-05-03 20:38:40 +00:00
|
|
|
nonFreeResponseBets,
|
|
|
|
nonFreeResponseComments,
|
2022-06-18 03:28:16 +00:00
|
|
|
tips,
|
2022-05-03 20:38:40 +00:00
|
|
|
contract
|
|
|
|
)
|
|
|
|
)
|
2022-04-29 21:11:04 +00:00
|
|
|
|
2022-04-26 21:08:50 +00:00
|
|
|
items.push({
|
|
|
|
type: 'commentInput',
|
|
|
|
id: 'commentInput',
|
|
|
|
contract,
|
2022-05-18 14:42:13 +00:00
|
|
|
betsByCurrentUser: nonFreeResponseBets.filter(
|
|
|
|
(bet) => bet.userId === user?.id
|
|
|
|
),
|
|
|
|
commentsByCurrentUser: nonFreeResponseComments.filter(
|
|
|
|
(comment) => comment.userId === user?.id
|
|
|
|
),
|
2022-04-26 21:08:50 +00:00
|
|
|
})
|
|
|
|
break
|
2022-05-26 21:41:24 +00:00
|
|
|
}
|
2022-05-03 20:38:40 +00:00
|
|
|
case 'free-response-comment-answer-groups':
|
|
|
|
items.push(
|
|
|
|
...getAnswerAndCommentInputGroups(
|
2022-06-01 02:42:35 +00:00
|
|
|
contract as FreeResponseContract,
|
2022-05-03 20:38:40 +00:00
|
|
|
bets,
|
|
|
|
comments,
|
2022-06-18 03:28:16 +00:00
|
|
|
tips,
|
2022-05-03 20:38:40 +00:00
|
|
|
user
|
|
|
|
)
|
|
|
|
)
|
|
|
|
break
|
2022-04-26 21:08:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return items.reverse()
|
2022-03-14 20:29:32 +00:00
|
|
|
}
|