Use feed "mode". Clean up cases.

This commit is contained in:
James Grugett 2022-03-11 18:48:32 -06:00
parent 29e33bc0ac
commit 679871dbc5
8 changed files with 54 additions and 98 deletions

View File

@ -90,7 +90,8 @@ export function AnswerItem(props: {
bets={[]} bets={[]}
comments={[]} comments={[]}
user={user} user={user}
outcome={answer.id} filterToOutcome={answer.id}
mode="all"
/> />
)} )}
</Col> </Col>

View File

@ -124,6 +124,7 @@ export const ContractOverview = (props: {
bets={bets} bets={bets}
comments={comments} comments={comments}
user={user} user={user}
mode="all"
betRowClassName="!mt-0" betRowClassName="!mt-0"
/> />
</Col> </Col>

View File

@ -8,16 +8,15 @@ import { Bet } from '../../../common/bet'
import { useUser } from '../../hooks/use-user' import { useUser } from '../../hooks/use-user'
import BetRow from '../bet-row' import BetRow from '../bet-row'
import { FeedQuestion } from './feed-items' import { FeedQuestion } from './feed-items'
import { ContractActivity, RecentContractActivity } from './contract-activity' import { ContractActivity } from './contract-activity'
export function ActivityFeed(props: { export function ActivityFeed(props: {
contracts: Contract[] contracts: Contract[]
recentBets: Bet[] recentBets: Bet[]
recentComments: Comment[] recentComments: Comment[]
loadBetAndCommentHistory?: boolean mode: 'only-recent' | 'abbreviated' | 'all'
}) { }) {
const { contracts, recentBets, recentComments, loadBetAndCommentHistory } = const { contracts, recentBets, recentComments, mode } = props
props
const user = useUser() const user = useUser()
@ -30,24 +29,15 @@ export function ActivityFeed(props: {
return ( return (
<FeedContainer <FeedContainer
contracts={contracts} contracts={contracts}
renderContract={(contract) => renderContract={(contract) => (
loadBetAndCommentHistory ? ( <ContractActivity
<ContractActivity user={user}
user={user} contract={contract}
contract={contract} bets={groupedBets[contract.id] ?? []}
bets={groupedBets[contract.id] ?? []} comments={groupedComments[contract.id] ?? []}
comments={groupedComments[contract.id] ?? []} mode={mode}
abbreviated />
/> )}
) : (
<RecentContractActivity
user={user}
contract={contract}
bets={groupedBets[contract.id] ?? []}
comments={groupedComments[contract.id] ?? []}
/>
)
}
/> />
) )
} }

View File

@ -87,7 +87,8 @@ function groupBets(
comments: Comment[], comments: Comment[],
windowMs: number, windowMs: number,
contract: Contract, contract: Contract,
userId?: string userId: string | undefined,
hideOutcome: boolean
) { ) {
const commentsMap = mapCommentsByBetId(comments) const commentsMap = mapCommentsByBetId(comments)
const items: ActivityItem[] = [] const items: ActivityItem[] = []
@ -103,7 +104,7 @@ function groupBets(
bets: [...group], bets: [...group],
id: group[0].id, id: group[0].id,
contract, contract,
hideOutcome: false, hideOutcome,
}) })
} }
group = [] group = []
@ -118,10 +119,10 @@ function groupBets(
comment, comment,
bet, bet,
contract, contract,
showOutcomeLabel: true, showOutcomeLabel: !hideOutcome,
truncate: true, truncate: true,
} }
: { type: 'bet' as const, id: bet.id, bet, contract, hideOutcome: false } : { type: 'bet' as const, id: bet.id, bet, contract, hideOutcome }
} }
for (const bet of bets) { for (const bet of bets) {
@ -227,7 +228,9 @@ export function getAllContractActivityItems(
? [{ type: 'createanswer', id: answer.id, contract, answer }] ? [{ type: 'createanswer', id: answer.id, contract, answer }]
: [{ type: 'description', id: '0', contract }] : [{ type: 'description', id: '0', contract }]
items.push(...groupBets(bets, comments, DAY_IN_MS, contract, user?.id)) items.push(
...groupBets(bets, comments, DAY_IN_MS, contract, user?.id, !!outcome)
)
if (contract.closeTime && contract.closeTime <= Date.now()) { if (contract.closeTime && contract.closeTime <= Date.now()) {
items.push({ type: 'close', id: `${contract.closeTime}`, contract }) items.push({ type: 'close', id: `${contract.closeTime}`, contract })
@ -248,12 +251,10 @@ export function getRecentContractActivityItems(
bets = bets.sort((b1, b2) => b1.createdTime - b2.createdTime) bets = bets.sort((b1, b2) => b1.createdTime - b2.createdTime)
comments = comments.sort((c1, c2) => c1.createdTime - c2.createdTime) comments = comments.sort((c1, c2) => c1.createdTime - c2.createdTime)
const items: ActivityItem[] = [] const items: ActivityItem[] =
items.push( contract.outcomeType === 'FREE_RESPONSE'
...(contract.outcomeType === 'FREE_RESPONSE'
? getAnswerGroups(contract, bets, comments, user) ? getAnswerGroups(contract, bets, comments, user)
: groupBets(bets, comments, DAY_IN_MS, contract, user?.id)) : groupBets(bets, comments, DAY_IN_MS, contract, user?.id, false)
)
// Remove all but last bet group. // Remove all but last bet group.
const betGroups = items.filter((item) => item.type === 'betgroup') const betGroups = items.filter((item) => item.type === 'betgroup')

View File

@ -1,4 +1,4 @@
import _ from 'lodash' import _, { update } from 'lodash'
import { Contract } from '../../lib/firebase/contracts' import { Contract } from '../../lib/firebase/contracts'
import { Comment } from '../../lib/firebase/comments' import { Comment } from '../../lib/firebase/comments'
@ -17,24 +17,33 @@ export function ContractActivity(props: {
bets: Bet[] bets: Bet[]
comments: Comment[] comments: Comment[]
user: User | null | undefined user: User | null | undefined
outcome?: string // Which multi-category outcome to filter mode: 'only-recent' | 'abbreviated' | 'all'
abbreviated?: boolean filterToOutcome?: string // Which multi-category outcome to filter
betRowClassName?: string betRowClassName?: string
}) { }) {
const { contract, user, outcome, abbreviated, betRowClassName } = props const { contract, user, filterToOutcome, mode, betRowClassName } = props
const comments = useComments(contract.id) ?? props.comments const updatedComments =
const bets = useBets(contract.id) ?? props.bets // eslint-disable-next-line react-hooks/rules-of-hooks
mode === 'only-recent' ? undefined : useComments(contract.id)
const comments = updatedComments ?? props.comments
let items = getAllContractActivityItems( // eslint-disable-next-line react-hooks/rules-of-hooks
contract, const updatedBets = mode === 'only-recent' ? undefined : useBets(contract.id)
bets, const bets = updatedBets ?? props.bets
comments,
user,
outcome
)
if (abbreviated) { let items =
mode === 'only-recent'
? getRecentContractActivityItems(contract, bets, comments, user)
: getAllContractActivityItems(
contract,
bets,
comments,
user,
filterToOutcome
)
if (mode === 'abbreviated') {
items = [items[0], ...items.slice(-3)] items = [items[0], ...items.slice(-3)]
} }
@ -42,29 +51,6 @@ export function ContractActivity(props: {
<FeedItems <FeedItems
contract={contract} contract={contract}
items={items} items={items}
feedType={abbreviated ? 'activity' : 'market'}
betRowClassName={betRowClassName}
outcome={outcome}
/>
)
}
export function RecentContractActivity(props: {
contract: Contract
bets: Bet[]
comments: Comment[]
user: User | null | undefined
betRowClassName?: string
}) {
const { contract, bets, comments, user, betRowClassName } = props
const items = getRecentContractActivityItems(contract, bets, comments, user)
return (
<FeedItems
contract={contract}
items={items}
feedType="activity"
betRowClassName={betRowClassName} betRowClassName={betRowClassName}
/> />
) )

View File

@ -48,24 +48,13 @@ import { Answer } from '../../../common/answer'
import { ActivityItem } from './activity-items' import { ActivityItem } from './activity-items'
import { User } from '../../../common/user' import { User } from '../../../common/user'
export type FeedType =
// Main homepage/fold feed,
| 'activity'
// Comments feed on a market
| 'market'
// Grouped for a multi-category outcome
| 'multi'
export function FeedItems(props: { export function FeedItems(props: {
contract: Contract contract: Contract
items: ActivityItem[] items: ActivityItem[]
feedType: FeedType
outcome?: string // Which multi-category outcome to filter
betRowClassName?: string betRowClassName?: string
}) { }) {
const { contract, items, feedType, outcome, betRowClassName } = props const { contract, items, betRowClassName } = props
const { outcomeType } = contract const { outcomeType } = contract
const isBinary = outcomeType === 'BINARY'
return ( return (
<div className="flow-root pr-2 md:pr-0"> <div className="flow-root pr-2 md:pr-0">
@ -102,7 +91,7 @@ export function FeedItems(props: {
</div> </div>
))} ))}
</div> </div>
{isBinary && tradingAllowed(contract) && ( {outcomeType === 'BINARY' && tradingAllowed(contract) && (
<BetRow contract={contract} className={clsx('mb-2', betRowClassName)} /> <BetRow contract={contract} className={clsx('mb-2', betRowClassName)} />
)} )}
</div> </div>
@ -529,8 +518,7 @@ function FeedCreateAnswer(props: { contract: Contract; answer: Answer }) {
name={answer.name} name={answer.name}
username={answer.username} username={answer.username}
/>{' '} />{' '}
submitted answer <OutcomeLabel outcome={answer.id} />{' '} submitted this answer <Timestamp time={answer.createdTime} />
<Timestamp time={contract.createdTime} />
</div> </div>
</div> </div>
</> </>
@ -731,15 +719,3 @@ function FeedExpand(props: { setExpanded: (expanded: boolean) => void }) {
</> </>
) )
} }
// On 'multi' feeds, the outcome is redundant, so we hide it
function MaybeOutcomeLabel(props: { outcome: string; feedType: FeedType }) {
const { outcome, feedType } = props
return feedType === 'multi' ? null : (
<span>
{' '}
of <OutcomeLabel outcome={outcome} />
{/* TODO: Link to the correct e.g. #23 */}
</span>
)
}

View File

@ -246,7 +246,7 @@ export default function FoldPage(props: {
contracts={activeContracts} contracts={activeContracts}
recentBets={recentBets ?? []} recentBets={recentBets ?? []}
recentComments={recentComments ?? []} recentComments={recentComments ?? []}
loadBetAndCommentHistory mode="abbreviated"
/> />
{activeContracts.length === 0 && ( {activeContracts.length === 0 && (
<div className="mx-2 mt-4 text-gray-500 lg:mx-0"> <div className="mx-2 mt-4 text-gray-500 lg:mx-0">

View File

@ -131,6 +131,7 @@ const Home = (props: {
contracts={activeContracts} contracts={activeContracts}
recentBets={recentBets} recentBets={recentBets}
recentComments={recentComments} recentComments={recentComments}
mode="only-recent"
/> />
) : ( ) : (
<LoadingIndicator className="mt-4" /> <LoadingIndicator className="mt-4" />