Remove unused acitivity items-related code (#492)

* Remove unused acitivity items

* Remove activity page
This commit is contained in:
Ian Philips 2022-06-14 07:13:24 -06:00 committed by GitHub
parent 716e00374c
commit e49f614acb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 14 additions and 497 deletions

View File

@ -1,38 +0,0 @@
import { Contract } from 'web/lib/firebase/contracts'
import { Comment } from 'web/lib/firebase/comments'
import { Col } from '../layout/col'
import { Bet } from 'common/bet'
import { useUser } from 'web/hooks/use-user'
import { ContractActivity } from './contract-activity'
export function ActivityFeed(props: {
feed: {
contract: Contract
recentBets: Bet[]
recentComments: Comment[]
}[]
mode: 'only-recent' | 'abbreviated' | 'all'
getContractPath?: (contract: Contract) => string
}) {
const { feed, mode, getContractPath } = props
const user = useUser()
return (
<Col className="gap-2">
{feed.map((item) => (
<ContractActivity
key={item.contract.id}
className="rounded-md bg-white py-6 px-2 sm:px-4"
user={user}
contract={item.contract}
bets={item.recentBets}
comments={item.recentComments}
mode={mode}
contractPath={
getContractPath ? getContractPath(item.contract) : undefined
}
/>
))}
</Col>
)
}

View File

@ -1,4 +1,4 @@
import { last, findLastIndex, uniq, sortBy } from 'lodash'
import { uniq, sortBy } from 'lodash'
import { Answer } from 'common/answer'
import { Bet } from 'common/bet'
@ -6,14 +6,11 @@ import { getOutcomeProbability } from 'common/calculate'
import { Comment } from 'common/comment'
import { Contract, FreeResponseContract } from 'common/contract'
import { User } from 'common/user'
import { mapCommentsByBetId } from 'web/lib/firebase/comments'
export type ActivityItem =
| DescriptionItem
| QuestionItem
| BetItem
| CommentItem
| BetGroupItem
| AnswerGroupItem
| CloseItem
| ResolveItem
@ -49,15 +46,6 @@ export type BetItem = BaseActivityItem & {
hideComment?: boolean
}
export type CommentItem = BaseActivityItem & {
type: 'comment'
comment: Comment
betsBySameUser: Bet[]
probAtCreatedTime?: number
truncate?: boolean
smallAvatar?: boolean
}
export type CommentThreadItem = BaseActivityItem & {
type: 'commentThread'
parentComment: Comment
@ -65,12 +53,6 @@ export type CommentThreadItem = BaseActivityItem & {
bets: Bet[]
}
export type BetGroupItem = BaseActivityItem & {
type: 'betgroup'
bets: Bet[]
hideOutcome: boolean
}
export type AnswerGroupItem = BaseActivityItem & {
type: 'answergroup'
user: User | undefined | null
@ -87,172 +69,6 @@ export type ResolveItem = BaseActivityItem & {
type: 'resolve'
}
const DAY_IN_MS = 24 * 60 * 60 * 1000
const ABBREVIATED_NUM_COMMENTS_OR_BETS_TO_SHOW = 3
// Group together bets that are:
// - Within a day of the first in the group
// (Unless the bets are older: then are grouped by 7-days.)
// - Do not have a comment
// - Were not created by this user
// Return a list of ActivityItems
function groupBets(
bets: Bet[],
comments: Comment[],
contract: Contract,
userId: string | undefined,
options: {
hideOutcome: boolean
abbreviated: boolean
smallAvatar: boolean
reversed: boolean
}
) {
const { hideOutcome, abbreviated, smallAvatar, reversed } = options
const commentsMap = mapCommentsByBetId(comments)
const items: ActivityItem[] = []
let group: Bet[] = []
// Turn the current group into an ActivityItem
function pushGroup() {
if (group.length == 1) {
items.push(toActivityItem(group[0]))
} else if (group.length > 1) {
items.push({
type: 'betgroup',
bets: [...group],
id: group[0].id,
contract,
hideOutcome,
})
}
group = []
}
function toActivityItem(bet: Bet): ActivityItem {
const comment = commentsMap[bet.id]
return comment
? {
type: 'comment' as const,
id: bet.id,
comment,
betsBySameUser: [bet],
contract,
truncate: abbreviated,
smallAvatar,
}
: {
type: 'bet' as const,
id: bet.id,
bet,
contract,
hideOutcome,
smallAvatar,
}
}
for (const bet of bets) {
const isCreator = userId === bet.userId
// If first bet in group is older than 3 days, group by 7 days. Otherwise, group by 1 day.
const windowMs =
Date.now() - (group[0]?.createdTime ?? bet.createdTime) > DAY_IN_MS * 3
? DAY_IN_MS * 7
: DAY_IN_MS
if (commentsMap[bet.id] || isCreator) {
pushGroup()
// Create a single item for this
items.push(toActivityItem(bet))
} else {
if (
group.length > 0 &&
bet.createdTime - group[0].createdTime > windowMs
) {
// More than `windowMs` has passed; start a new group
pushGroup()
}
group.push(bet)
}
}
if (group.length > 0) {
pushGroup()
}
const abbrItems = abbreviated
? items.slice(-ABBREVIATED_NUM_COMMENTS_OR_BETS_TO_SHOW)
: items
if (reversed) abbrItems.reverse()
return abbrItems
}
function getAnswerGroups(
contract: FreeResponseContract,
bets: Bet[],
comments: Comment[],
user: User | undefined | null,
options: {
sortByProb: boolean
abbreviated: boolean
reversed: boolean
}
) {
const { sortByProb, abbreviated, reversed } = options
let outcomes = uniq(bets.map((bet) => bet.outcome))
if (abbreviated) {
const lastComment = last(comments)
const lastCommentOutcome = bets.find(
(bet) => bet.id === lastComment?.betId
)?.outcome
const lastBetOutcome = last(bets)?.outcome
if (lastCommentOutcome && lastBetOutcome) {
outcomes = uniq([
...outcomes.filter(
(outcome) =>
outcome !== lastCommentOutcome && outcome !== lastBetOutcome
),
lastCommentOutcome,
lastBetOutcome,
])
}
outcomes = outcomes.slice(-2)
}
if (sortByProb) {
outcomes = sortBy(outcomes, (outcome) =>
getOutcomeProbability(contract, outcome)
)
} else {
// Sort by recent bet.
outcomes = sortBy(outcomes, (outcome) =>
findLastIndex(bets, (bet) => bet.outcome === outcome)
)
}
const answerGroups = outcomes
.map((outcome) => {
const answer = contract.answers?.find(
(answer) => answer.id === outcome
) as Answer
// TODO: this doesn't abbreviate these groups for activity feed anymore
return {
id: outcome,
type: 'answergroup' as const,
contract,
user,
answer,
comments,
bets,
}
})
.filter((group) => group.answer)
if (reversed) answerGroups.reverse()
return answerGroups
}
function getAnswerAndCommentInputGroups(
contract: FreeResponseContract,
bets: Bet[],
@ -284,54 +100,6 @@ function getAnswerAndCommentInputGroups(
return answerGroups
}
function groupBetsAndComments(
bets: Bet[],
comments: Comment[],
contract: Contract,
userId: string | undefined,
options: {
hideOutcome: boolean
abbreviated: boolean
smallAvatar: boolean
reversed: boolean
}
) {
const { smallAvatar, abbreviated, reversed } = options
// Comments in feed don't show user's position?
const commentsWithoutBets = comments
.filter((comment) => !comment.betId)
.map((comment) => ({
type: 'comment' as const,
id: comment.id,
contract: contract,
comment,
betsBySameUser: [],
truncate: abbreviated,
smallAvatar,
}))
const groupedBets = groupBets(bets, comments, contract, userId, options)
// iterate through the bets and comment activity items and add them to the items in order of comment creation time:
const unorderedBetsAndComments = [...commentsWithoutBets, ...groupedBets]
const sortedBetsAndComments = sortBy(unorderedBetsAndComments, (item) => {
if (item.type === 'comment') {
return item.comment.createdTime
} else if (item.type === 'bet') {
return item.bet.createdTime
} else if (item.type === 'betgroup') {
return item.bets[0].createdTime
}
})
const abbrItems = abbreviated
? sortedBetsAndComments.slice(-ABBREVIATED_NUM_COMMENTS_OR_BETS_TO_SHOW)
: sortedBetsAndComments
if (reversed) abbrItems.reverse()
return abbrItems
}
function getCommentThreads(
bets: Bet[],
comments: Comment[],
@ -351,122 +119,6 @@ function getCommentThreads(
return items
}
export function getAllContractActivityItems(
contract: Contract,
bets: Bet[],
comments: Comment[],
user: User | null | undefined,
options: {
abbreviated: boolean
}
) {
const { abbreviated } = options
const { outcomeType } = contract
const reversed = true
bets =
outcomeType === 'BINARY'
? bets.filter((bet) => !bet.isAnte && !bet.isRedemption)
: bets.filter((bet) => !(bet.isAnte && (bet.outcome as string) === '0'))
const items: ActivityItem[] = abbreviated
? [
{
type: 'question',
id: '0',
contract,
showDescription: false,
},
]
: [{ type: 'description', id: '0', contract }]
if (outcomeType === 'FREE_RESPONSE') {
const onlyUsersBetsOrBetsWithComments = bets.filter((bet) =>
comments.some(
(comment) => comment.betId === bet.id || bet.userId === user?.id
)
)
items.push(
...groupBetsAndComments(
onlyUsersBetsOrBetsWithComments,
comments,
contract,
user?.id,
{
hideOutcome: false,
abbreviated,
smallAvatar: false,
reversed,
}
)
)
} else {
items.push(
...groupBetsAndComments(bets, comments, contract, user?.id, {
hideOutcome: false,
abbreviated,
smallAvatar: false,
reversed,
})
)
}
if (contract.closeTime && contract.closeTime <= Date.now()) {
items.push({ type: 'close', id: `${contract.closeTime}`, contract })
}
if (contract.resolution) {
items.push({ type: 'resolve', id: `${contract.resolutionTime}`, contract })
}
if (reversed) items.reverse()
return items
}
export function getRecentContractActivityItems(
contract: Contract,
bets: Bet[],
comments: Comment[],
user: User | null | undefined,
options: {
contractPath?: string
}
) {
const { contractPath } = options
bets = bets.sort((b1, b2) => b1.createdTime - b2.createdTime)
comments = comments.sort((c1, c2) => c1.createdTime - c2.createdTime)
const questionItem: QuestionItem = {
type: 'question',
id: '0',
contract,
showDescription: false,
contractPath,
}
const items = []
if (contract.outcomeType === 'FREE_RESPONSE') {
items.push(
...getAnswerGroups(contract, bets, comments, user, {
sortByProb: false,
abbreviated: true,
reversed: true,
})
)
} else {
items.push(
...groupBetsAndComments(bets, comments, contract, user?.id, {
hideOutcome: false,
abbreviated: true,
smallAvatar: false,
reversed: true,
})
)
}
return [questionItem, ...items]
}
function commentIsGeneralComment(comment: Comment, contract: Contract) {
return (
comment.answerOutcome === undefined &&

View File

@ -3,11 +3,7 @@ import { Comment } from 'web/lib/firebase/comments'
import { Bet } from 'common/bet'
import { useBets } from 'web/hooks/use-bets'
import { useComments } from 'web/hooks/use-comments'
import {
getAllContractActivityItems,
getRecentContractActivityItems,
getSpecificContractActivityItems,
} from './activity-items'
import { getSpecificContractActivityItems } from './activity-items'
import { FeedItems } from './feed-items'
import { User } from 'common/user'
import { useContractWithPreload } from 'web/hooks/use-contract'
@ -17,45 +13,27 @@ export function ContractActivity(props: {
bets: Bet[]
comments: Comment[]
user: User | null | undefined
mode:
| 'only-recent'
| 'abbreviated'
| 'all'
| 'comments'
| 'bets'
| 'free-response-comment-answer-groups'
mode: 'comments' | 'bets' | 'free-response-comment-answer-groups'
contractPath?: string
className?: string
betRowClassName?: string
}) {
const { user, mode, contractPath, className, betRowClassName } = props
const { user, mode, className, betRowClassName } = props
const contract = useContractWithPreload(props.contract) ?? props.contract
const updatedComments =
// eslint-disable-next-line react-hooks/rules-of-hooks
mode === 'only-recent' ? undefined : useComments(contract.id)
const updatedComments = useComments(contract.id)
const comments = updatedComments ?? props.comments
const updatedBets =
// eslint-disable-next-line react-hooks/rules-of-hooks
mode === 'only-recent' ? undefined : useBets(contract.id)
const updatedBets = useBets(contract.id)
const bets = (updatedBets ?? props.bets).filter((bet) => !bet.isRedemption)
const items =
mode === 'only-recent'
? getRecentContractActivityItems(contract, bets, comments, user, {
contractPath,
})
: mode === 'comments' ||
mode === 'bets' ||
mode === 'free-response-comment-answer-groups'
? getSpecificContractActivityItems(contract, bets, comments, user, {
mode,
})
: // only used in abbreviated mode with folds/communities, all mode isn't used
getAllContractActivityItems(contract, bets, comments, user, {
abbreviated: mode === 'abbreviated',
})
const items = getSpecificContractActivityItems(
contract,
bets,
comments,
user,
{ mode }
)
return (
<FeedItems

View File

@ -30,11 +30,10 @@ import { RelativeTimestamp } from '../relative-timestamp'
import { FeedAnswerCommentGroup } from 'web/components/feed/feed-answer-comment-group'
import {
FeedCommentThread,
FeedComment,
CommentInput,
TruncatedComment,
} from 'web/components/feed/feed-comments'
import { FeedBet, FeedBetGroup } from 'web/components/feed/feed-bets'
import { FeedBet } from 'web/components/feed/feed-bets'
import { NumericContract } from 'common/contract'
export function FeedItems(props: {
@ -82,12 +81,8 @@ export function FeedItem(props: { item: ActivityItem }) {
return <FeedQuestion {...item} />
case 'description':
return <FeedDescription {...item} />
case 'comment':
return <FeedComment {...item} />
case 'bet':
return <FeedBet {...item} />
case 'betgroup':
return <FeedBetGroup {...item} />
case 'answergroup':
return <FeedAnswerCommentGroup {...item} />
case 'close':

View File

@ -1,70 +0,0 @@
import React, { useEffect, useState } from 'react'
import Router, { useRouter } from 'next/router'
import { Page } from 'web/components/page'
import { ActivityFeed } from 'web/components/feed/activity-feed'
import { Spacer } from 'web/components/layout/spacer'
import { Col } from 'web/components/layout/col'
import { useUser } from 'web/hooks/use-user'
import { LoadingIndicator } from 'web/components/loading-indicator'
import { useAlgoFeed } from 'web/hooks/use-algo-feed'
import { ContractPageContent } from './[username]/[contractSlug]'
import { CategorySelector } from '../components/feed/category-selector'
export default function Activity() {
const user = useUser()
const [category, setCategory] = useState<string>('all')
const feed = useAlgoFeed(user, category)
const router = useRouter()
const { u: username, s: slug } = router.query
const contract = feed?.find(
({ contract }) => contract.slug === slug
)?.contract
useEffect(() => {
// If the page initially loads with query params, redirect to the contract page.
if (router.isReady && slug && username) {
Router.replace(`/${username}/${slug}`)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [router.isReady])
if (user === null) {
Router.replace('/')
return <></>
}
return (
<>
<Page suspend={!!contract}>
<Col className="mx-auto w-full max-w-[700px]">
<CategorySelector category={category} setCategory={setCategory} />
<Spacer h={1} />
{feed ? (
<ActivityFeed
feed={feed}
mode="only-recent"
getContractPath={(c) =>
`activity?u=${c.creatorUsername}&s=${c.slug}`
}
/>
) : (
<LoadingIndicator className="mt-4" />
)}
</Col>
</Page>
{contract && (
<ContractPageContent
contract={contract}
username={contract.creatorUsername}
slug={contract.slug}
bets={[]}
comments={[]}
backToHome={router.back}
/>
)}
</>
)
}