manifold/web/components/feed/activity-feed.tsx
James Grugett 93287f8dc1
Answers in feed (#63)
* Compute answer group feed items

* Refactor feed code into 5 files under feed directory.

* Convert to typed ActivityItems

* Use feed "mode". Clean up cases.

* Implement feed answer groups!

* FR: Use nested comments/bets under answers for contract page. filter more items out of FR feed.

* Linkify answer text on activity feed

* Default feed excluded tags are case insensitive

* Show followed folds first

* Allow filtering your trades

* Store users's last sort in localstorage

* Use avatar of user that submitted answer and name instead of pencil icon. Spacing. Show up to 3 comments in asnwer group.

* Don't reveal market creator's bets

* Fix communites feed to be abbreviated

* Remove complicated answer group logic

Co-authored-by: Austin Chen <akrolsmir@gmail.com>
2022-03-14 15:29:32 -05:00

100 lines
2.6 KiB
TypeScript

import _ from 'lodash'
import clsx from 'clsx'
import { Contract, tradingAllowed } from '../../lib/firebase/contracts'
import { Comment } from '../../lib/firebase/comments'
import { Col } from '../layout/col'
import { Bet } from '../../../common/bet'
import { useUser } from '../../hooks/use-user'
import BetRow from '../bet-row'
import { FeedQuestion } from './feed-items'
import { ContractActivity } from './contract-activity'
export function ActivityFeed(props: {
contracts: Contract[]
recentBets: Bet[]
recentComments: Comment[]
mode: 'only-recent' | 'abbreviated' | 'all'
}) {
const { contracts, recentBets, recentComments, mode } = props
const user = useUser()
const groupedBets = _.groupBy(recentBets, (bet) => bet.contractId)
const groupedComments = _.groupBy(
recentComments,
(comment) => comment.contractId
)
return (
<FeedContainer
contracts={contracts}
renderContract={(contract) => (
<ContractActivity
user={user}
contract={contract}
bets={groupedBets[contract.id] ?? []}
comments={groupedComments[contract.id] ?? []}
mode={mode}
/>
)}
/>
)
}
export function SummaryActivityFeed(props: { contracts: Contract[] }) {
const { contracts } = props
return (
<FeedContainer
contracts={contracts}
renderContract={(contract) => <ContractSummary contract={contract} />}
/>
)
}
function FeedContainer(props: {
contracts: Contract[]
renderContract: (contract: Contract) => any
}) {
const { contracts, renderContract } = props
return (
<Col className="items-center">
<Col className="w-full max-w-3xl">
<Col className="w-full divide-y divide-gray-300 self-center bg-white">
{contracts.map((contract) => (
<div key={contract.id} className="py-6 px-2 sm:px-4">
{renderContract(contract)}
</div>
))}
</Col>
</Col>
</Col>
)
}
function ContractSummary(props: {
contract: Contract
betRowClassName?: string
}) {
const { contract, betRowClassName } = props
const { outcomeType } = contract
const isBinary = outcomeType === 'BINARY'
return (
<div className="flow-root pr-2 md:pr-0">
<div className={clsx(tradingAllowed(contract) ? '' : '-mb-8')}>
<div className="relative pb-8">
<div className="relative flex items-start space-x-3">
<FeedQuestion contract={contract} showDescription />
</div>
</div>
</div>
{isBinary && tradingAllowed(contract) && (
<BetRow contract={contract} className={clsx('mb-2', betRowClassName)} />
)}
</div>
)
}